如何在C#中找出一个大字符串(或子字符串)出现的次数?最佳方法是什么?

4
我曾经为学校做过一个作业,虽然我已经提交了,但是我写的代码很糟糕,我不喜欢最终结果。所以,我很好奇,在C#中解决以下问题的最佳方法是什么:

'//4 Alice in Wonderland书中“queen”出现了多少次?编写一些代码来计数它们。'

书的链接(pastebin):book

我的代码(pastebin):my code (ugly)

请在回答时忽略我的代码。同时,请解释你的代码是如何实现的,以及为什么你认为这是最佳解决方案。

单词 “queen” 在这本书中出现的次数应该是 76 次。

6
你应该去查看http://codereview.stackexchange.com/。它专为代码审查而创建,而stackoverflow则更多地设计为帮助解决破损的代码问题。 - Derek Van Cuyk
请查看String.IndexOf() - Thomas Weller
8
你询问了“最佳”方式,但没有说明你对好的标准是什么。最短的代码?最易于理解的代码?面对变化最灵活的代码?使用最少内存的代码?在单次运行中最快的代码?如果允许预计算,那么最快的代码是哪一个?这些以及许多其他因素都可能是你在设计实际代码时需要考虑的指标。 - Eric Lippert
1
@user3499284 关键是最佳解决方案取决于实际需求。Eric列出的所有事情基本上都是同样有效的,因此你会得到不同的答案来回答“最佳”,每个人的答案都不尽相同,这最终并没有太大帮助。 - Kyle
可能是https://dev59.com/ZXRB5IYBdhLWcg3wtZMV的重复问题,如何计算一个字符串在另一个字符串中出现的次数。 - Thomas Weller
显示剩余5条评论
5个回答

4
我不会发布完整的代码,因为我认为让您尝试一下这个练习是有用的,但我个人会选择使用IndexOf重载版本来解决问题,它可以设置起始位置。所以大概是这样的(注意:意图上是错误的):
int startingPosition = 0;
int numberOfOccurrences = 0;
do {
  startingPosition = fullText.IndexOf("queen", startingPosition);
  numberOfOccurrences++;
} while( matchFound );

2

最简便的写法是使用正则表达式,它可以为你查找匹配项,只需获取计数即可。此外,正则表达式还有忽略大小写选项,因此您不必在大字符串上使用 ToLower。因此,在读取文件后,您可以直接使用正则表达式。

string aliceFile = Path.Combine(Environment.CurrentDirectory, "bestanden\\alice_in_wonderland.txt");
string text = File.ReadAllText(aliceFile);

Regex r = new Regex("queen", RegexOptions.IgnoreCase);
var count = r.Matches(input).Count;

另外,由于输入内容非常庞大但模式很简单,您可以使用RegexOptions.Compiled来加速处理。

Regex r = new Regex("queen", RegexOptions.IgnoreCase | RegexOptions.Compiled);
var count = r.Matches(input).Count;

1
你可以编写一个字符串扩展方法来分割多个字符....
public static string[] Split(this string s, string separator)
{
    return s.Split(new string[] { separator }, StringSplitOptions.None);
}

只需将您要搜索的字符串用作分隔符,然后结果就是数组长度减1。

string s = "How now brown cow";
string searchS = "ow";
int count = s.split( seacrchS ).Length- 1;

实际由split返回的数组将是....
["H"," n"," b","n ","c"]

扩展方法在未来总是非常有用。


1

也可以使用正则表达式:

 string s = "Hello my baby, Hello my honey, Hello my ragtime gal";
 int count = Regex.Matches(s, "Hello").Count;

比现在的牛还要更加优美动听 ;)而且代码也非常不错。 - AntDC
我可能会添加一个扩展方法CountOccurances并利用它。 - AntDC

0

或者您可以使用一些 Linq 来完成相同的事情

string words = "Hi, Hi, Hello, Hi, Hello";  //"hello1 hello2 hello546 helloasdf";
var countList = words.Split(new[] { " " }, StringSplitOptions.None);
int count = countList.Where(s => s.Contains("Hi")).Count();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接