获取字符串中第n个char出现的索引

Kyl*_* V. 18 .net c# string

我正在尝试创建一个函数,该函数返回字符串中给定char的第N次出现的索引.

这是我的尝试:

private int IndexOfNth(string str, char c, int n)
{
    int index = str.IndexOf(c) + 1;
    if (index >= 0)
    {
        string temp = str.Substring(index, str.Length - index);
        for (int j = 1; j < n; j++)
        {
            index = temp.IndexOf(c) + 1;
            if (index < 0)
            {
                return -1;
            }
            temp = temp.Substring(index, temp.Length - index);
        }
        index = index + (str.Length);
    }
    return index;
}
Run Code Online (Sandbox Code Playgroud)

应该找到第一个匹配项,切断字符串的前部,从新的子字符串中找到第一个匹配项,然后打开直到它获得第n个匹配项的索引.但是,我没有考虑最终子字符串的索引将如何偏离原始字符串中的原始实际索引.我该如何工作?

另外作为一个附带问题,如果我想将char作为制表符,我是否通过此函数'\ t'或者什么?

Ry-*_*Ry- 40

不要那样做; IndexOf采用第二个参数指定从哪里开始.

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


Jon*_*eet 23

考虑到所有这些子串对我来说似乎很浪费.为什么不循环自己呢?

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

(我考虑IndexOf在像minitech的解决方案中使用循环,但确定它有点繁琐.当然,两者都很好.两者基本上都做同样的工作,只检查每个字符一次.使用IndexOf可能稍微更高效,但去哪个你发现更具可读性.)


Mar*_*age 15

使用LINQ查找a字符串中的第5个索引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;
Run Code Online (Sandbox Code Playgroud)

  • @StickFigs:如果没有第一个项目,`.FirstOrDefault()``返回null`,所以你不能得到`i`财产(?或者是匿名类型的字段),你想`-1` . (2认同)
  • @TimSchmelter:我不需要使用`ToCharArray`.谢谢你指出来. (2认同)

Amy*_*y B 6

我倾向于首先考虑如何使用Linq访问该集合.

  // 0-based n.
char result = str
  .Where(x => x == c)
  .Skip(n)
  .FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

然后我将解压缩linq并添加索引迭代.

int foundCount = -1;
for(int position = 0; position < str.Length; position++)
{
  char x = str[position];
  if (x == c)
  {
    foundCount += 1;
    // 0-based n
    if (foundCount == n)
    {
      return position;
    }
  }
}
return -1;
Run Code Online (Sandbox Code Playgroud)

然后我想一想:如果这个方法返回所有索引,那么我可以查询它们:

public IEnumerable<int> IndexesOf(string str, char c)
{
  for(int position = 0; position < str.Length; position++)
  {
    char x = str[position];
    if (x == c)
    {
      yield return position;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

被称为:

int position = IndexesOf(str, c)
 .Skip(n) // 0-based n
 .DefaultIfEmpty(-1)
 .First();
Run Code Online (Sandbox Code Playgroud)