to linuxyf(率人哥哥) 是啊,我的写错了,好像应该是Regex r = new Regex(@"(\.\.)"); 呵呵,对不起了,楼主,就当是顶了一把.
to linuxyf(率人哥哥): 你误解我的意思了。我是写了一正则,但太复杂,才决定将判断字符串是否有连续的两个英文句点从原来的正则中提取出来。现在正犹豫是加一个函数还是再加一个正则。 lovvver(春晖)好像赞同dong6(立冬)的函数。我不太了解IndexOf和正则的内部实现,但IndexOf应该和C++中string的strstr函数差不多。谁能解释一下函数和正则的优缺点?
to ssdjmcj8048(经营和挣钱) : 如果是对同一个很长的字符串进行多次搜索,而其每次搜索的内容也不相同用建立索引等办法自然要比简单的for快的多。但是这个问题不然,他搜索的内容是特定的而且只搜索一次,并且每次被搜索的字符串也不相同。无论你采用什么算法也是是至少要访问每个字符一次才可以建立起加速查找所需要的索引信息。然后你还要使用这个索引信息快速的定位你要查找的子串。这样无论你怎么努力最后的结果都是平均访问字符的次数都要多于一次。简单的说,你所说的方法适合针对不变的通常也是很大的字符串每次搜索字符串内不同的内容。而这个问题是要搜索的内容已经定下来了,每次被搜索的字符串不同,这样的问题dfa是f是非常快的。
to LiuDian(薛定谔的猫) 索引是多次全文搜索的范畴,不再这里讨论; 这里仅仅讨论在长度为n的字符串A中搜索长度为m的字符串b,如果m为1,那么任何算法的都是一样的,都是n次比较;如果m大于1,那么比较次数可能是n*(1至m)的次数比较,m越大,简单搜索算法效率越低,这个时候就会很多高级的搜索算法来降低比较次数,而这些算法非常多,大家可以去看看数据结构的书,或者baidu一下。大家在这里总是提到正则,而且总是在说它是最快,试问你们的依据是什么,就是感觉么?大家有空还是复习一下大学课程,不要拿一个不是很了解的技术来盲目套用。看了我写的这些文字大家有人一定比较生气,我也不高兴,而更多的是无奈
To LiuDian(薛定谔的猫): 既然是测IndexOf 和 Regex,Regex的构造当然要放在测试速度的循环里。====================================================测试加密压缩算法是不是也要把加密器和压缩器的构造放到测试速度的循环里?Regex本来就不是这么用的,这是故意降低效率的用法。我们要测试的是他们在搜索字符串上的效率差别,而不是初始化环境的区别。你把IndexOf也加上一个字符串解析的时间,那速度还不是差上几十倍。那干脆说Console程序比Winfoem程序快很多好了。
if (s.IndexOf("..")>-1)
{
有
}
using System.Text.RegularExpressions;
string str = "abc..cde";
Regex r = new Regex(@"[\.\.]+");
if (r.IsMatch(str))
{
//存在
}
else
{
//不存在
}
bool FoundMatch = false;
try {
FoundMatch = Regex.IsMatch(SubjectString, "\\,\\,");
} catch (ArgumentException ex) {
// Syntax error in the regular expression
}
bool FoundMatch = false;
try {
FoundMatch = Regex.IsMatch(SubjectString, "\\.\\.");
} catch (ArgumentException ex) {
// Syntax error in the regular expression
}
FoundMatch = Regex.IsMatch(SubjectString, "\\.\\.");只这一条语句,你怎么能说有两个Regex来判断了???
对于不了解正则的人,你可以这样误解,但对于稍微了解一点正则知识的人来说,你这这样认为,就说不过去了。诚然,正则是让一些初学者感觉晦涩难懂,主要是pattern的编写部分,因为有很多特殊的符号和规则需要记住,需要熟练掌握,所以感觉难。对于字符串的处理,正则就像SQL在关系数据库中所扮演的角色一般。
呵呵,对不起了,楼主,就当是顶了一把.
你误解我的意思了。我是写了一正则,但太复杂,才决定将判断字符串是否有连续的两个英文句点从原来的正则中提取出来。现在正犹豫是加一个函数还是再加一个正则。
lovvver(春晖)好像赞同dong6(立冬)的函数。我不太了解IndexOf和正则的内部实现,但IndexOf应该和C++中string的strstr函数差不多。谁能解释一下函数和正则的优缺点?
int i = str.Length - 1;
for(;i>0;i--)
{
if ((str[i]=='.') && (str[i-1] == '.'))
{
return true;
}
}
return false;
这个和IndexOf和正则相比怎末样?
一般我只用IndexOf
int i = str.Length - 1;
for(;i>0;i--)
{
if ((str[i]=='.') && (str[i-1] == '.'))
{
return true;
}
}
return false;
这个和IndexOf和正则相比差的比较远,你可以写段代码测试一下
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
foreach( char ch in str.ToCharArray() )
{
if ( ch == '.' )
{
if ( flag )
return true;
else
{
flag = true;
continue;
}
flag = false;
}
}
...
使用indexof就足够了,何必那么累;看了一下.net源码,string.indexof确实考虑很多问题,比如字符串编码、语言等问题,最后调用居然是非托管的函数去搞的;由此可认为linuxyf(率人哥哥) 的效率会高一些;但是如果是比较大的字符串,还是indexof效率高。
可不能说这样的话啊,越是大字符串,越能体现正则的速度。
{
if ((str.Length >= 2) && (str[0] == '_'))
{
return (str[1] == '_');
}
return false;
}//这个应该效率比较高,不然ms不会这么写呀。
不知楼主发这个贴的目的是为了研究算法还是在项目中需要。如果只是项目中需要那么用正则表达式是最好的了,可能很多人认为正则表达式很复杂所以一定效率很低,其实不并不是这样,一个regexp在使用前会被转换成DFA(确定性有限自动机),用字符串作为这个自动机的输入,无论regexp多么复杂字符串内的字符最多只被访问一次,理论上regexp应该是最快的(难道还有比只查看一次更快的么^_^),但是使用regexp的时候一定要注意,因为从regexp到dfa转换过程因为算法比较复杂,所以在.net里面regex对象要保证只构造一次,然后用这个对象去匹配字符串,而不要每次匹配字符串都从新new Regex。
如果楼主是为了研究算法那么我推荐的算法是使用dfa,关于dfa的知识可以去看一些关于形式化语言的书,很多编译原理方面的书也有讲述。
我的版面里有个编程比赛贴,比赛题目和这个问题有一定联系,有兴趣的朋友可以去看看。
http://community.csdn.net/Expert/topic/4490/4490851.xml?temp=.6696131
如果是对同一个很长的字符串进行多次搜索,而其每次搜索的内容也不相同用建立索引等办法自然要比简单的for快的多。但是这个问题不然,他搜索的内容是特定的而且只搜索一次,并且每次被搜索的字符串也不相同。无论你采用什么算法也是是至少要访问每个字符一次才可以建立起加速查找所需要的索引信息。然后你还要使用这个索引信息快速的定位你要查找的子串。这样无论你怎么努力最后的结果都是平均访问字符的次数都要多于一次。简单的说,你所说的方法适合针对不变的通常也是很大的字符串每次搜索字符串内不同的内容。而这个问题是要搜索的内容已经定下来了,每次被搜索的字符串不同,这样的问题dfa是f是非常快的。
索引是多次全文搜索的范畴,不再这里讨论;
这里仅仅讨论在长度为n的字符串A中搜索长度为m的字符串b,如果m为1,那么任何算法的都是一样的,都是n次比较;如果m大于1,那么比较次数可能是n*(1至m)的次数比较,m越大,简单搜索算法效率越低,这个时候就会很多高级的搜索算法来降低比较次数,而这些算法非常多,大家可以去看看数据结构的书,或者baidu一下。大家在这里总是提到正则,而且总是在说它是最快,试问你们的依据是什么,就是感觉么?大家有空还是复习一下大学课程,不要拿一个不是很了解的技术来盲目套用。看了我写的这些文字大家有人一定比较生气,我也不高兴,而更多的是无奈
:linuxyf(率人哥哥) 给出的Regex算法。第四种是shifind(浪子哲) 的算法。我做了一个测试。速度比分别为5:25:27:1
所以shifind(浪子哲) 给出的算法最优。
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(永远的菜鸟) 能说一下你的测试方法吗?
if (s.IndexOf("..")>-1)
{
有
}
if (Regex.IsMatch(email, @"\.\."))
{
}
else
{
}
绝对不能用Regex.IsMatch(email, @"\.\."))
而要使用:
Regex twoDot = new Regex(@"\.\.");//而且这句也不能放到测试速度的循环里
.....
....
twoDot.IsMatch(email);
正则表达式在对字符串进行match之前要转换成一种内部表示,一般是一个dfa。这个过程非常缓慢。第一种写法测试的时间是对正则表达式进行编译和对字符串进行match时间的和。我也测试了,在字符串很短的时候正则表达式和indexof差不多。 字符串很长的时候者则表达式要慢很多。估计是.net的正则表达式内部的状态迁移函数实现的太垃圾。java里面的情况好的多。
既然是测IndexOf 和 Regex,Regex的构造当然要放在测试速度的循环里。
To LiuDian(薛定谔的猫):
既然是测IndexOf 和 Regex,Regex的构造当然要放在测试速度的循环里。====================================================测试加密压缩算法是不是也要把加密器和压缩器的构造放到测试速度的循环里?Regex本来就不是这么用的,这是故意降低效率的用法。我们要测试的是他们在搜索字符串上的效率差别,而不是初始化环境的区别。你把IndexOf也加上一个字符串解析的时间,那速度还不是差上几十倍。那干脆说Console程序比Winfoem程序快很多好了。
string Pattern = "..";
MatchCollection Matches =Regex.Matches(Text,Pattern,
RegexOptions.IgnoreCase|
RegexOptions.ExplicitCapture);
foreach(Match NextMatch in Matches)
{
Console.WriteLine(NextMatch.Index);
}
这样子是不是也可以啊,我初学,不太懂
测试两种方法,要把它们放在同一起跑线上。这有什末疑问吗?RegexRegex的优势根本就不在于处理这些简单的字符串操作。另外,即使把Regex的构造不放在测试速度的循环里,它也比IndexOf慢。
if (s.IndexOf("..")>-1)
{
有
}