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

时间:2012-10-07 03:11:09

标签: c#

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

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

7 个答案:

答案 0 :(得分: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

答案 1 :(得分:11)

我使用以下扩展方法来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);
    }
}

用法:

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

答案 2 :(得分: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);

答案 3 :(得分:5)

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

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

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

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

答案 4 :(得分:5)

原始迭代总是更好&amp;最优化的。

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

所以我建议继续:

var foundIndexes = new List<int>();

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

     if (myStr[i] == 'a') foundIndexes.Add(i);

答案 5 :(得分:0)

    public static List<int> GetSubstringLocations(string text, string searchsequence)
    {
        try
        {
            List<int> foundIndexes = new List<int> { };

            int i = 0;
            while (i < text.Length)
            {
                int cindex = text.IndexOf(searchsequence, i);

                if (cindex >= 0)
                {
                    foundIndexes.Add(cindex);
                    i = cindex;
                }

                i++;

            }

            return foundIndexes;
        }
        catch (Exception ex) { }
        return new List<int> { };
    }

答案 6 :(得分:0)

public static String[] Split(this string s,char c = '\t')
    {
        if (s == null) return null;
        var a = new List<int>();
        int i = s.IndexOf(c);
        if (i < 0) return new string[] { s };
        a.Add(i);
        for (i = i+1; i < s.Length; i++) if (s[i] == c) a.Add(i);
        var result = new string[a.Count +1];            
        int startIndex = 0;
        result[0] = s.Remove(a[0]);
        for(i=0;i<a.Count-1;i++)
        {
            result[i + 1] = s.Substring(a[i] + 1, a[i + 1] - a[i] - 1);
        }
        result[a.Count] = s.Substring(a[a.Count - 1] + 1);
        return result;
    }