Get index of nth occurrence of char in a string

后端 未结 9 1789
情书的邮戳
情书的邮戳 2020-12-06 00:44

I\'m trying to make a function that returns the index of the Nth occurrence of a given char in a string.

Here is my attempt:

private int IndexOfNth(s         


        
相关标签:
9条回答
  • 2020-12-06 01:00

    Don't do that; IndexOf takes a second parameter that specifies where to start.

    private static int IndexOfNth(string str, char c, int n) {
        int s = -1;
    
        for (int i = 0; i < n; i++) {
            s = str.IndexOf(c, s + 1);
    
            if (s == -1) break;
        }
    
        return s;
    }
    
    0 讨论(0)
  • 2020-12-06 01:02

    Using LINQ to find the index of the 5'th a in the string aababaababa:

    var str = "aababaababa";
    var ch = 'a';
    var n = 5;
    var result = str
      .Select((c, i) => new { c, i })
      .Where(x => x.c == ch)
      .Skip(n - 1)
      .FirstOrDefault();
    return result != null ? result.i : -1;
    
    0 讨论(0)
  • 2020-12-06 01:06

    Instead of creating a bunch of substrings, why not use the IndexOf overload that takes a starting index? This will be both easier (you won't have to adjust the final index) and more efficient (you don't have to allocate a bunch of substrings).

    0 讨论(0)
  • 2020-12-06 01:07

    Not tested but something like this should work:

    private int IndexOfNth(string str, char c, int n)
    {
        int index = -1;
        while (n-- > 0)
        {
            index = str.IndexOf(c, index + 1);
            if (index == -1) break;
        }
        return index;
    }
    
    0 讨论(0)
  • 2020-12-06 01:11

    Hadn't seen anyone use the CharEnumerator yet...

        public Int32 getNthIndex(string str, char c, Int32 n)
        {
            Int32 index = 0;
            Int32 count = 0;
            if (str != null && str.Length > 0 && !(n < 1))
            {
                CharEnumerator scanner = str.GetEnumerator();
                while (scanner.MoveNext())
                {
                    if (scanner.Current == c) { count++; }
                    if (count == n) { break; }
                    index++;
                }
                if (count < n) { index = -1; }
            }
            if (count == 0) { return -1; } else { return index; }
        }
    

    Should be pretty efficient, no substrings or anything, just scan through the string you're given and keep count.

    0 讨论(0)
  • 2020-12-06 01:13

    Taking all these substrings seems pretty wasteful to me. Why not just loop yourself?

    private int IndexOfNth(string str, char c, int n)
    {
        int remaining = n;
        for (int i = 0; i < str.Length; i++)
        {
            if (str[i] == c)
            {
                remaining--;
                if (remaining == 0)
                {
                    return i;
                }
            }
        }
        return -1;
    }
    

    (I considered using IndexOf in a loop like minitech's solution, but decided it was a bit fiddly. Either's fine, of course. Both basically do the same work, only ever checking each character once. Using IndexOf may be slightly more efficient, but go for whichever you find more readable.)

    0 讨论(0)
提交回复
热议问题