CSharp - 如何计算字符串出现在另一个字符串中的次数?

  显示原文与译文双语对照的内容

我在做一些事情,我意识到我想计算多少 / 可以在字符串中找到多少个,然后它击中了我,但是我无法决定最好的( 或者最容易) 是什么。

现在我将使用类似于:


string source ="/once/upon/a/time/";
int count = source.Length - source.Replace("/","").Length;

但我根本不喜欢,任何人?

我真的不想把 正规表达式 挖掘出来,我想?

我知道我的字符串会有我正在搜索的词,所以你可以假设。

当然,对于长度为> 1的字符串,


string haystack ="/once/upon/a/time";
string needle ="/";
int needleCount = ( haystack.Length - source.Replace(needle,"").Length )/needle.Length

时间:

如果你使用. NET 3.5,你可以使用 LINQ:


int count = source.Count(f => f == '/');

如果你不想使用 LINQ,你可以使用:


int count = source.Split('/').Length - 1;


你可能会惊讶地发现,你的原始技术比任何一种都快 30% ! 我刚刚用"/once/upon time/" 完成了一个快速测试,结果如下:

你的原始= 12
source.Count = 19
source.Split = 17
foreach ( 来自 bobwienholt的答案) = 10

( 时间是 50,000,000迭代,所以你不可能在现实世界中看到很多差异。)

如果你想搜索整个字符串,而不仅仅是字符:


src.Select((c, i) => src.Substring(i)).Count(sub => sub.StartsWith(target))

读取为字符串中的每个字符,以字符串开头的字符串作为子字符串;如果它以目标字符串开始,则计算它。"

LINQ在所有集合中工作,因为字符串只是一个字符集合,这个漂亮的小one-liner如何:


var count = source.Count(c => c == '/');

我已经做了一些研究,发现在大多数情况下,watson解的是最快的。 这是 post ( 除了使用 正规表达式,因为它在解析字符串像"test{test中每个解决方案结果的表


 Name | Short/char | Long/char | Short/short| Long/short | Long/long |
 Inspite | 134| 1853| 95| 1146| 671|
 LukeH_1 | 346| 4490| N/A| N/A| N/A|
 LukeH_2 | 152| 1569| 197| 2425| 2171|
Bobwienholt | 230| 3269| N/A| N/A| N/A|
Richard Watson| 33| 298| 146| 737| 543|
StefanosKargas| N/A| N/A| 681| 11884| 12486|

你可以看到,如果发现数量出现短子( 1 -5个字符) 总之 string(10-50 characters) 原算法者优先。

另外,对于multicharacter子字符串,你应该使用以下代码( 基于watson解决方案的Richard )


int count = 0, n = 0;

if(substring!="")
{
 while ((n = source.IndexOf(substring, n, StringComparison.InvariantCulture))!= -1)
 {
 n += substring.Length;
 ++count;
 }
}

这两者只适用于single-character搜索术语。。


countOccurences("the","the answer is the answer");

int countOccurences(string needle, string haystack)
{
 return (haystack.Length - haystack.Replace(needle,"").Length)/needle.Length;
}

可能会变成更长的针。

但必须有一种更优雅的方式。 : )


string source ="/once/upon/a/time/";
int count = 0;
int n = 0;

while ((n = source.IndexOf('/', n))!= -1)
{
 n++;
 count++;
}

我的电脑它是 2秒速度比 for-every-character 50百万迭代的解决方案。

2013修订版:

将字符串更改为 char [] 并迭代。 为 50 m 迭代的总时间缩短或者缩短2 !


char[] testchars = source.ToCharArray();
foreach (char c in testchars)
{
 if (c == '/')
 count++;
}

这更快:


char[] testchars = source.ToCharArray();
int length = testchars.Length;
for (int n = 0; n <length; n++)
{
 if (testchars[n] == '/')
 count++;
}

为了获得良好的度量,从数组末尾到 0的迭代似乎是最快的,大约是 5% 。


int length = testchars.Length;
for (int n = length-1; n> = 0; n--)
{
 if (testchars[n] == '/')
 count++;
}

我很好奇为什么这可能是google( 我记得关于反向迭代的更快) 周围,和来到这个烦人的问题使用字符串字符 [] 技术了。 我认为反转技巧在这个上下文中是新的,尽管。

在 C# 中迭代单个字符的最快方法是什么

...