在字符串内计数的巧妙解决方案

时间:2010-01-04 02:06:45

标签: c# string

我正在尝试解决以下问题但无法找到优雅的解决方案。有任何想法吗? 感谢。

输入 - 可变长度的数字字符串,例如, string str =“5557476374202110373551116201”;

任务 - 检查(从左到右)每个数字(忽略重复)不会出现在以下2个索引中。使用例如。上面,第一个数字= 5.忽略代表我们看到组中的最后一个索引5是2.所以我们检查接下来的2个索引,即3和4不应该有5.如果是,我们将其视为错误。目标是计算字符串中的此类错误。

在上面的字符串中,错误位于索引3,10和16处。

4 个答案:

答案 0 :(得分:5)

除了其他优秀的解决方案,您还可以使用简单的正则表达式:

foreach (Match m in Regexp.Matches(str, @"(\d)(?!\1)(?=\d\1)"))
    Console.WriteLine("Error: " + m.Index);

返回3,10,16。这将使用具有反向引用的前瞻匹配相邻错误。处理重复。 .net应该支持这一点。如果没有,您可以使用非反向引用版本:

(?<=0[^0])0|(?<=1[^1])1|(?<=2[^2])2|(?<=3[^3])3|(?<=4[^4])4|(?<=5[^5])5|(?<=6[^6])6|(?<=7[^7])7|(?<=8[^8])8|(?<=9[^9])9

答案 1 :(得分:3)

一个简单的索引for循环,如果检查有效,可以先看几下。您可以将字符串视为char []或IEnumerable - 无论哪种方式,您都可以使用它来遍历所有字符并执行先行检查以查看以下一个或两个字符是否重复。

答案 2 :(得分:2)

对不起,不是C#man,但这是Ruby中的简单解决方案:

a="5557476374202110373551116201"
0.upto(a.length) do |i|
  puts "error at #{i}" if a[i]!=a[i+1] && a[i]==a[i+2]
end

输出:

error at 3
error at 10
error at 16

答案 3 :(得分:1)

这是我在C#中汇总的东西,它使用了问题的示例输入。我没有彻底检查过,但是......

public static IEnumerable<int> GetErrorIndices(string text) {
    if (string.IsNullOrEmpty(text))
        yield break;

    int i = 0;
    while (i < text.Length) {
        char c = text[i];

        // get the index of the next character that isn't a repetition
        int nextIndex = i + 1;
        while (nextIndex < text.Length && text[nextIndex] == c)
            nextIndex++;

        // if we've reached the end of the string, there's no error
        if (nextIndex + 1 >= text.Length)
            break;

        // we actually only care about text[nextIndex + 1],
        // NOT text[nextIndex] ... why? because text[nextIndex]
        // CAN'T be a repetition (we already skipped to the first
        // non-repetition)
        if (text[nextIndex + 1] == c)
            yield return i;

        i = nextIndex;
    }

    yield break;
}