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

Mar*_*k W 23 c#

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

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

m.z*_*zam 24

你可以使用String.IndexOf,见下面的例子:

    string s = "abcabcabcabcabc";
    var foundIndexes = new List<int>();

    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
Run Code Online (Sandbox Code Playgroud)

  • 我只想指出使用“StopWatch”而不是扣除“基准”侧的刻度 (2认同)

fub*_*ubo 13

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

public static IEnumerable<int> AllIndexesOf(this string str, string searchstring)
{
    int minIndex = str.IndexOf(searchstring);
    while (minIndex != -1)
    {
        yield return minIndex;
        minIndex = str.IndexOf(searchstring, minIndex + searchstring.Length);
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

IEnumerable<int> result = "foobar".AllIndexesOf("o"); // [1,2]
Run Code Online (Sandbox Code Playgroud)


Nik*_*wal 9

怎么样

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);
Run Code Online (Sandbox Code Playgroud)

  • 单循环与否,它不是更快,它只是卷曲应该是一段简单的代码. (2认同)
  • LINQ几乎总是比强制执行同样的事情要慢.LINQ-to-objects依赖于委托,委托是有效的函数指针.将为源可枚举中的每个元素调用指针.函数指针调用*不能由C#编译器,JIT或主机CPU优化.它们在每种实用方法中都比内联代码慢得多.(我不是说永远不要使用LINQ,但请注意,为了可读性和可维护性,您要交易性能 - 假设您的LINQ代码是可读和可维护的.) (2认同)
  • 发布单行文章真是太糟糕了。任何体面的 .NET 程序员都知道使用 linq 是一种性能权衡,就像@cdhowie 所说的那样。我不会使用这个解决方案,因为我的作品对性能更重要。对于一个一次性的人来说,这是完美的。并感谢海报为了我们的方便而将其放在这里 (2认同)

lox*_*xxy 6

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

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

所以我建议继续:

var foundIndexes = new List<int>();

for (int i = 0; i < myStr.Length; i++)

     if (myStr[i] == 'a') foundIndexes.Add(i);
Run Code Online (Sandbox Code Playgroud)


cdh*_*wie 5

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

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

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

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