获取字符串中字符的所有索引的更有效方法

而不是循环遍历每个字符以查看它是否是您想要的那个,然后将您的索引添加到列表中,如下所示:

var foundIndexes = new List(); for (int i = 0; i < myStr.Length; i++) { if (myStr[i] == 'a') foundIndexes.Add(i); } 

您可以使用String.IndexOf ,请参阅下面的示例:

  string s = "abcabcabcabcabc"; var foundIndexes = new List(); long t1 = DateTime.Now.Ticks; for (int i = s.IndexOf('a'); i > -1; i = s.IndexOf('a', i + 1)) { // for loop end when i=-1 ('a' not found) foundIndexes.Add(i); } long t2 = DateTime.Now.Ticks - t1; // read this value to see the run time 

我使用以下扩展方法来yield所有结果:

 public static IEnumerable AllIndexesOf(this string str, string searchstring) { int minIndex = str.IndexOf(searchstring); while (minIndex != -1) { yield return minIndex; minIndex = str.IndexOf(searchstring, minIndex + searchstring.Length); } } 

用法:

 IEnumerable result = "foobar".AllIndexesOf("o"); // [1,2] 

怎么样

 string xx = "The quick brown fox jumps over the lazy dog"; char search = 'f'; var result = xx.Select((b, i) => b.Equals(search) ? i : -1).Where(i => i != -1); 

如果字符串很短,则搜索字符串一次并计算字符出现的次数可能更有效,然后分配该大小的数组并再次搜索字符串,在数组中记录索引。 这将跳过任何列表重新分配。

它归结为字符串的长度和字符出现的次数。 如果字符串很长并且字符出现几次,则搜索一次并将标记附加到List会更快。 如果角色多次出现,那么搜索字符串两次(一次计数,一次填充数组)可能会更快。 究竟哪里的临界点取决于许多因素,这些因素无法从您的问题中推断出来。

如果您需要在字符串中搜索多个不同的字符并分别获取这些字符的索引列表,则可能更快一次搜索字符串并构建Dictionary> (或List>使用来自\0字符偏移作为指示到外部数组中)。

最终,您应该对应用程序进行基准测试以找出瓶颈。 通常,我们认为执行缓慢的代码实际上非常快,我们将大部分时间用于阻止I / O或用户输入。

原始迭代总是更好,最优化。

除非这是一项复杂的任务,否则您永远不需要寻求更好的优化解决方案……

所以我建议继续:

 var foundIndexes = new List(); for (int i = 0; i < myStr.Length; i++) if (myStr[i] == 'a') foundIndexes.Add(i);