判断字符串是否有连续的两个英文句点(.)求最佳算法

解决方案 »

  1.   

    string s="asdlkjfasdf..dfasd";
    if (s.IndexOf("..")>-1)
    {

    }
      

  2.   

    使用正则表达式:
    using System.Text.RegularExpressions;
    string str = "abc..cde";
    Regex r = new Regex(@"[\.\.]+");
    if (r.IsMatch(str))
    {
        //存在
    }
    else
    {
        //不存在
    }
      

  3.   

    使用正则是最好的选择
    bool FoundMatch = false;
    try {
    FoundMatch = Regex.IsMatch(SubjectString, "\\,\\,");
    } catch (ArgumentException ex) {
    // Syntax error in the regular expression
    }
      

  4.   

    不好意思,句点写成逗点了
    bool FoundMatch = false;
    try {
    FoundMatch = Regex.IsMatch(SubjectString, "\\.\\.");
    } catch (ArgumentException ex) {
    // Syntax error in the regular expression
    }
      

  5.   

    swordragon(古道热肠)给出的正则错了,只有一个句点的时候也会匹配成功。
      

  6.   

    正是因为用Regex判断字符串太复杂,才将判断字符串是否有连续的两个英文句点从Regex中提出来以降低Regex的复杂度,原来的Regex判断其他的规则。如果像swordragon(古道热肠) 和linuxyf(率人哥哥)所说的那样,就要用用两个Regex来判断。不太好判断函数和Regex的优缺点,请教这个方案和一个Regex加一个函数的优缺点。
      

  7.   

    楼主,你觉得正则表达式来处理字符串的匹配,split,replace这类任务复杂吗?如果你这样认为,那就是你对正则表达式的认识不够的问题了。
    FoundMatch = Regex.IsMatch(SubjectString, "\\.\\.");只这一条语句,你怎么能说有两个Regex来判断了???
    对于不了解正则的人,你可以这样误解,但对于稍微了解一点正则知识的人来说,你这这样认为,就说不过去了。诚然,正则是让一些初学者感觉晦涩难懂,主要是pattern的编写部分,因为有很多特殊的符号和规则需要记住,需要熟练掌握,所以感觉难。对于字符串的处理,正则就像SQL在关系数据库中所扮演的角色一般。
      

  8.   

    to linuxyf(率人哥哥) 是啊,我的写错了,好像应该是Regex r = new Regex(@"(\.\.)");
    呵呵,对不起了,楼主,就当是顶了一把.
      

  9.   

    to linuxyf(率人哥哥):
    你误解我的意思了。我是写了一正则,但太复杂,才决定将判断字符串是否有连续的两个英文句点从原来的正则中提取出来。现在正犹豫是加一个函数还是再加一个正则。
    lovvver(春晖)好像赞同dong6(立冬)的函数。我不太了解IndexOf和正则的内部实现,但IndexOf应该和C++中string的strstr函数差不多。谁能解释一下函数和正则的优缺点?
      

  10.   

    javascript里的正则反正比纯字符串操作函数来操作性能好,它好像把算法高速缓存了不知道怎么了。
      

  11.   

    string str = "a..b";
                int i = str.Length - 1;
                for(;i>0;i--)
                {
                    if ((str[i]=='.') && (str[i-1] == '.')) 
                    { 
                        return true;
                    }
                }
                return false;
    这个和IndexOf和正则相比怎末样?
      

  12.   

    MARK  
    一般我只用IndexOf
      

  13.   

    string str = "a..b";
    int i = str.Length - 1;
    for(;i>0;i--)
    {
    if ((str[i]=='.') && (str[i-1] == '.'))
    {
    return true;
    }
    }
    return false;
    这个和IndexOf和正则相比差的比较远,你可以写段代码测试一下
      

  14.   

    可以参考MS的判断字符串是不是以 2个下划线开头的代码在 System.Runtime.Remoting.Channels.StringHelper下找。
    Vb.net:
    Friend Shared Function StartsWithDoubleUnderscore(ByVal str As String) As Boolean
          If ((str.Length >= 2) AndAlso (str.Chars(0) = "_"c)) Then
                Return (str.Chars(1) = "_"c)
          End If
          Return False
    End Function 
    C#:
    internal static bool StartsWithDoubleUnderscore(string str)
    {
          if ((str.Length >= 2) && (str[0] == '_'))
          {
                return (str[1] == '_');
          }
          return false;
    }
    所以:回复人: linuxyf(率人哥哥) 的性能比较高的! 
    ====CSDN 小助手 V2.5 ====
    CSDN小助手是一款脱离浏览器也可以访问Csdn论坛的软件
    速度快;使用方便;提供源代码。
    界面:http://blog.csdn.net/Qqwwee_Com/category/146601.aspx
    下载:http://szlawbook.com/csdnv2
      

  15.   

    ...bool flag = false;
    foreach( char ch in str.ToCharArray() )
    {
      if ( ch == '.' )
      {
        if ( flag )
          return true;
        else
        {
          flag = true;
          continue;
        }
        flag = false;
      }
    }
    ...
      

  16.   

    关于字符串搜索,数据结构书上有很权威的方法介绍;
    使用indexof就足够了,何必那么累;看了一下.net源码,string.indexof确实考虑很多问题,比如字符串编码、语言等问题,最后调用居然是非托管的函数去搞的;由此可认为linuxyf(率人哥哥) 的效率会高一些;但是如果是比较大的字符串,还是indexof效率高。
      

  17.   

    楼上的兄弟,没有测试过  “比较大的字符串,还是indexof效率高。”
    可不能说这样的话啊,越是大字符串,越能体现正则的速度。
      

  18.   

    IndexOf("..")>-1对于普通应用程序,最佳的算法,应当是可读性。可读性第一,效率第二。当然效率要在可以接受的范围内。
      

  19.   

    if (s.IndexOf("..")>-1)//这应该是简单的写法。internal static bool StartsWithDoubleUnderscore(string str)
    {
          if ((str.Length >= 2) && (str[0] == '_'))
          {
                return (str[1] == '_');
          }
          return false;
    }//这个应该效率比较高,不然ms不会这么写呀。
      

  20.   

    IndexOf("..")>-1对于普通应用程序,最佳的算法,应当是可读性。可读性第一,效率第二。当然效率要在可以接受的范围内。问:什么是普通应用程序?什么是可读性?
      

  21.   

    IndexOf("..")>-1应该是最好的,简单明了
      

  22.   

    我想楼主说的“最佳算法”应该指的是“速度最快的算法”不知道我猜测的对不对。
    不知楼主发这个贴的目的是为了研究算法还是在项目中需要。如果只是项目中需要那么用正则表达式是最好的了,可能很多人认为正则表达式很复杂所以一定效率很低,其实不并不是这样,一个regexp在使用前会被转换成DFA(确定性有限自动机),用字符串作为这个自动机的输入,无论regexp多么复杂字符串内的字符最多只被访问一次,理论上regexp应该是最快的(难道还有比只查看一次更快的么^_^),但是使用regexp的时候一定要注意,因为从regexp到dfa转换过程因为算法比较复杂,所以在.net里面regex对象要保证只构造一次,然后用这个对象去匹配字符串,而不要每次匹配字符串都从新new Regex。
    如果楼主是为了研究算法那么我推荐的算法是使用dfa,关于dfa的知识可以去看一些关于形式化语言的书,很多编译原理方面的书也有讲述。
    我的版面里有个编程比赛贴,比赛题目和这个问题有一定联系,有兴趣的朋友可以去看看。
    http://community.csdn.net/Expert/topic/4490/4490851.xml?temp=.6696131
      

  23.   

    最佳字符串搜索一般会有预测、排解的原理,不是简单访问一次就是最快,否则for循环的方法岂不就是最快,还研究什么算法
      

  24.   

    to ssdjmcj8048(经营和挣钱) :
    如果是对同一个很长的字符串进行多次搜索,而其每次搜索的内容也不相同用建立索引等办法自然要比简单的for快的多。但是这个问题不然,他搜索的内容是特定的而且只搜索一次,并且每次被搜索的字符串也不相同。无论你采用什么算法也是是至少要访问每个字符一次才可以建立起加速查找所需要的索引信息。然后你还要使用这个索引信息快速的定位你要查找的子串。这样无论你怎么努力最后的结果都是平均访问字符的次数都要多于一次。简单的说,你所说的方法适合针对不变的通常也是很大的字符串每次搜索字符串内不同的内容。而这个问题是要搜索的内容已经定下来了,每次被搜索的字符串不同,这样的问题dfa是f是非常快的。
      

  25.   

    to LiuDian(薛定谔的猫)
    索引是多次全文搜索的范畴,不再这里讨论;
    这里仅仅讨论在长度为n的字符串A中搜索长度为m的字符串b,如果m为1,那么任何算法的都是一样的,都是n次比较;如果m大于1,那么比较次数可能是n*(1至m)的次数比较,m越大,简单搜索算法效率越低,这个时候就会很多高级的搜索算法来降低比较次数,而这些算法非常多,大家可以去看看数据结构的书,或者baidu一下。大家在这里总是提到正则,而且总是在说它是最快,试问你们的依据是什么,就是感觉么?大家有空还是复习一下大学课程,不要拿一个不是很了解的技术来盲目套用。看了我写的这些文字大家有人一定比较生气,我也不高兴,而更多的是无奈
      

  26.   

    单就算法而论,这题不管使用上面哪种算法效果都差不多吧,楼上兄弟们讨论的似乎不是算法,而是实现方法了吧?不过我感觉对于这题,因为是连续两个.所以在搜索时,步进可以为2,而不是为1,不过这种算法最差时效果为2N(当全为单个点时),最好时为2/N,平均应该也是N左右吧,是不稳定算法,哈哈
      

  27.   

    判断标准是比较次数,一般来说n的m次方、n!、n*m几种级别
      

  28.   

    我可以很明确的答复你,第一种方法(IndexOf)比Regular的方法快出20倍。
      

  29.   

    这里有四种算法,第一种IndexOf,第二种是 :swordragon(古道热肠) 给出的Regex的方法,第三种是
    :linuxyf(率人哥哥) 给出的Regex算法。第四种是shifind(浪子哲) 的算法。我做了一个测试。速度比分别为5:25:27:1
    所以shifind(浪子哲) 给出的算法最优。
      

  30.   

    测试二是linuxyf(率人哥哥)给出的。
      

  31.   

    两个Regex方法可以看作一个,其程序如下:
    if (Regex.IsMatch(email, @"\.\."))
    {
        Console.WriteLine("Match");
    }
    else
    {
        Console.WriteLine("Not Match!");
    }IndexOf方法,其程序如下:
    if (email.IndexOf("..")>-1)
    {
        Console.WriteLine("Match");
    }
    else
    {
        Console.WriteLine("Not match!");
    }
    另写函数做了一点修改如下:(当遇到一个句点时,前进两个位置。对小字符串且含句点很少时,效率提升一点点。)
    bool fun(string str)
    {
        for (int i=0; i<str.Length-1; i++)
        {
            if ((str[i]=='.') && (str[++i] =='.'))
            {
                return true;
            }
        }
        return false;
    }
    if (fun(email))
    {
        Console.WriteLine("Match!");
    }
    else
    {
        Console.WriteLine("Not Match!");
    }这里只考虑普通字符串长度小于100,子串为两个字符(英文句点)。我用DateTime.Now.Ticks来测试循环执行10000次所耗时间,并不能测出各个方法的明显速度差(不会有翻倍的情况)。
    To: mlssun(永远的菜鸟) 能说一下你的测试方法吗?
      

  32.   

    string s="asdlkjfasdf..dfasd";
    if (s.IndexOf("..")>-1)
    {

    }
      

  33.   

    将Console.WriteLine("Match!");语句删掉,既可看出各个函数的明显速度差,我上面写的三个函数犯了同样的错误。对于这种情况Regex确实是最慢的。
    if (Regex.IsMatch(email, @"\.\."))
    {
    }
    else
    {
    }
      

  34.   

    可读性第一,不存在性能问题,所以我觉得IndexOf("..")>-1最好
      

  35.   

    上面例子犯了一个严重错误!!!!!!! 
    绝对不能用Regex.IsMatch(email, @"\.\."))
    而要使用:
    Regex twoDot = new Regex(@"\.\.");//而且这句也不能放到测试速度的循环里
    .....
    ....
    twoDot.IsMatch(email);
    正则表达式在对字符串进行match之前要转换成一种内部表示,一般是一个dfa。这个过程非常缓慢。第一种写法测试的时间是对正则表达式进行编译和对字符串进行match时间的和。我也测试了,在字符串很短的时候正则表达式和indexof差不多。 字符串很长的时候者则表达式要慢很多。估计是.net的正则表达式内部的状态迁移函数实现的太垃圾。java里面的情况好的多。
      

  36.   

    从可读性来说Regex.IsMatch(email, @"\.\."))和if (email.IndexOf("..")>-1)没什么区别,如果说Regex.IsMatch(email, @"\.\."))的可读性不好,这只能说明你在这方面知识的欠缺。Regex在.net中是有地位的,它在处理一些字符串时是有得天独厚的优势的。当然,IndexOf有时比Regex的性能好(比如这个例子),明白这一点,我们才能选择正确的方法。To LiuDian(薛定谔的猫):
    既然是测IndexOf 和 Regex,Regex的构造当然要放在测试速度的循环里。
      

  37.   


    To LiuDian(薛定谔的猫):
    既然是测IndexOf 和 Regex,Regex的构造当然要放在测试速度的循环里。====================================================测试加密压缩算法是不是也要把加密器和压缩器的构造放到测试速度的循环里?Regex本来就不是这么用的,这是故意降低效率的用法。我们要测试的是他们在搜索字符串上的效率差别,而不是初始化环境的区别。你把IndexOf也加上一个字符串解析的时间,那速度还不是差上几十倍。那干脆说Console程序比Winfoem程序快很多好了。
      

  38.   

    string Text = @"l;asdklsdaklkasdl;kdfl;akld;skdsl;akfdlskfldskfldskfl ..ddfsaj..adal..;.aads.a.";
                string Pattern = "..";
                MatchCollection Matches =Regex.Matches(Text,Pattern,
                    RegexOptions.IgnoreCase|
                    RegexOptions.ExplicitCapture);
                foreach(Match NextMatch in Matches)
                {
                    Console.WriteLine(NextMatch.Index);
                }
    这样子是不是也可以啊,我初学,不太懂
      

  39.   

    To: Ivony() 
    测试两种方法,要把它们放在同一起跑线上。这有什末疑问吗?RegexRegex的优势根本就不在于处理这些简单的字符串操作。另外,即使把Regex的构造不放在测试速度的循环里,它也比IndexOf慢。
      

  40.   

    string s="asdlkjfasdf..dfasd";
    if (s.IndexOf("..")>-1)
    {

    }