31

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

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

7 回答 7

27

您可以使用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
于 2012-10-07T03:29:19.770 回答
19

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]

边缘情况的旁注:这是一种适用于一个或多个字符的字符串方法。如果"fooo".AllIndexesOf("oo")结果只是1 https://dotnetfiddle.net/CPC7D2

于 2014-06-03T13:11:47.327 回答
10

怎么样

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);
于 2012-10-07T03:14:24.543 回答
7

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

除非它是一个有点复杂的任务,否则你永远不需要寻求更好的优化解决方案......

所以我建议继续:

var foundIndexes = new List<int>();

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

     if (myStr[i] == 'a') foundIndexes.Add(i);
于 2012-10-07T03:23:11.487 回答
5

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

归结为字符串的长度和字符出现的次数。如果字符串很长并且字符出现几次,则搜索一次并将索引附加到 aList<int>会更快。如果字符出现多次,那么搜索字符串两次(一次计数,一次填充数组)可能会更快。临界点的确切位置取决于许多无法从您的问题中推断出的因素。

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

最终,您应该对应用程序进行基准测试以发现瓶颈。通常,我们认为会执行缓慢的代码实际上非常快,并且我们将大部分时间都花在了 I/O 或用户输入上。

于 2012-10-07T03:22:33.543 回答
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> { };
    }
于 2019-12-10T16:05:36.880 回答
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;
    }
于 2020-07-10T11:34:55.693 回答