【问题标题】:How to get the indexes and reoccurrences of a specific character?如何获取特定字符的索引和重复出现?
【发布时间】:2013-10-10 10:58:04
【问题描述】:

如果字符串中有一个或多个字符反复出现。就像在下面的字符串中:

1+1+1-2+2/2*4-2*3/23

现在在上面的字符串中,+1,3,7 的索引处出现3 次,-5,13 的索引处出现2 次等等,然后将它们存储在 2维数组所以现在的问题是如何做到这一点。

【问题讨论】:

  • 怎么办?找到它,计算它,替换它?
  • 是要数符号还是需要它们的索引?
  • @HenkHolterman 我不想替换它,我只想存储它。
  • @HimBromBeere 我想将signsindexes 存储在一个数组中。

标签: c# string indexing character


【解决方案1】:

以下函数将返回给定搜索字符串的所有匹配索引:

List<int> GetAllIndices(string input, string search)
{
    List<int> result = new List<int>();

    int index = input.IndexOf(search);

    while(index != -1)
    {
        result.Add(index);
        index++;//increment to avoid matching the same index again
        if(index >= input.Length)//check if index is greater than string (causes exception)
            break;
        index = input.IndexOf(search, index);
    }

    return result;
}

它还应该处理重叠匹配,例如:搜索 "iii" 以查找出现的 "ii" 将返回 [0,1]


如果您想使用此函数创建符号列表及其索引,那么我会推荐以下方法:

string input = "1+1+1-2+2/2*4-2*3/23";

//create a dictionary to store the results
Dictionary<string, List<int>> results = new Dictionary<string, List<int>>();

//add results for + symbol
results.Add("+", GetAllIndices(input, "+"));

//add results for - symbol
results.Add("-", GetAllIndices(input, "-"));

//you can then access all indices for a given symbol like so
foreach(int index in results["+"])
{
    //do something with index
}

您甚至可以更进一步,将其包装在一个搜索多个符号的函数中:

Dictionary<string, List<int>> GetSymbolMatches(string input, params string[] symbols)
{
    Dictionary<string, List<int>> results = new Dictionary<string, List<int>>();

    foreach(string symbol in symbols)
    {
        results.Add(symbol, GetAllIndices(input, symbol));
    }

    return results;
}

然后你可以像这样使用它:

string input = "1+1+1-2+2/2*4-2*3/23";

Dictionary<string, List<int>> results = GetSymbolMatches(input, "+", "-", "*", "/");

foreach(int index in results["+"])
{
    //do something with index
}

【讨论】:

    【解决方案2】:

    使用 Linq:

    var allIndices = yourString.Select((c, i) => new { c, i, })
        .Where(a => a.c == '+').Select(a => a.i);
    

    获取包含字符串中所有字符的字典,例如:

    var allCharsAllIndices = yourString.Select((c, i) => new { c, i, })
        .GroupBy(a => a.c)
        .ToDictionary(g => g.Key, g => g.Select(a => a.i).ToArray());
    

    【讨论】:

    • 出色的 linq,但标准循环会更快,如果用户正在寻找的话。
    • @NicolasTyler 谢谢,但你怎么知道用户想要什么?
    【解决方案3】:

    您可以通过更改“值”来尝试此操作

    var duplicates = param1.ToCharArray().Select((item, index) => new { item, index })
                .Where(x =>x.item==VALUE).GroupBy(g=>g.index)
                 .Select(g => new { Key = g.Key  })
                .ToList();
    

    【讨论】:

    • 好,和我写的很接近,但你更早!备注:不需要ToCharArray(),因为System.String 本身已经是IEnumerable&lt;char&gt;,因此无需将数据复制到那里的数组中。 'CONDITION' 代表什么?你真的是想按g.index 分组吗?
    • 我写错了(并且用大写字符..shame :/ )你应该写值而不是条件。像“+”或“5”字符
    【解决方案4】:
    string msg = "1+1+1-2+2/2*4-2*3/23";
    Dictionary<char, List<int>> list = new Dictionary<char, List<int>>();
    for (int i = 0; i < msg.Length; i++)
    {
        if (!list.ContainsKey(msg[i]))
        {
            list.Add(msg[i], new List<int>());
            list[msg[i]].Add(i);
        }
        else
            list[msg[i]].Add(i);
    }
    

    【讨论】:

    • 这将计算所有实例,而不是获取索引列表
    • 考虑使用TryGetValue 而不是ContainsKey,然后使用list[...] 索引器访问(再次搜索刚刚找到的键)。
    【解决方案5】:

    简单 = 最好。没有内存分配。

    public static IEnumerable<int> GetIndexOfEvery(string haystack, string needle)
    {
      int index;
      int pos = 0;
      string s = haystack;
    
      while((index = s.IndexOf(needle)) != -1)
      {              
          yield return index + pos;
          pos = pos + index + 1;
          s = haystack.Substring(pos);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-29
      相关资源
      最近更新 更多