找到给定字符串中缺少的数字

时间:2013-10-08 10:24:42

标签: string algorithm

我发现这个面试问题浮出水面,经过深思熟虑之后,我无法为它制定合理的算法。

  

按顺序给出一串数字,找到丢失的数字。未给出数字范围。

     

样本输入:“9899100101103104105”

     

答案:102

4 个答案:

答案 0 :(得分:6)

这是一个简单的问题。

  1. 猜猜第一个数字的位数
  2. 逐个读取字符串中的数字。如果您读取的前一个数字是x,则下一个数字必须是x + 1或x + 2.如果是x + 2,请记住x + 1作为遗漏数字,继续直到字符串结尾以验证最初的猜测是正确的。如果您读取的内容不是x + 1或x + 2,则初始猜测错误,您需要重新启动(下一步)猜测。
  3. 用你的例子:

    9899100101103104105
    

    首先猜测长度为1

    read 9
    the next number should be either 10 or 11. Read the next two digits, you get 89.
    That is incorrect, so the initial guess was wrong.
    

    第二次猜测长度2

    read 98
    the next number should be either 99 or 100. Read the next two digits for 99
    the next number should be either 100 or 101. Read the next three digits for 100
    ... 101
    ... 103 (remember 102 as the missed number)
    ... 104
    ... 105
    end of input
    

    长度2的猜测被证实为正确的猜测,102报告为缺失的数字。

答案 1 :(得分:0)

当然,唯一不同的部分是弄清楚数字有多少位数。我看到两种方法。

  1. 为第一个数字尝试一定数量的数字,确定以下数字应该是什么(将有两个选项,具体取决于丢失的数字是否是第二个),并查看是否与以下字符串匹配的数字。如果是这样,继续。如果字符串不适合该模式,请使用不同的位数重试。
  2. 查看字符串的开头和结尾部分,并根据该字符串和字符串的长度来计算数字位数。这个更浪漫一点。

答案 2 :(得分:0)

  1. digits=1
  2. 解析字符串,就像第一个数字conatins digits数字一样。
  3. 解析下一个数字并检查它是否与最后解析的数字相关的顺序正确
  4. 如果减少,digit+=1,转到1.
  5. 如果它比最后一次解析高2,你可能会找到差距,解析其余部分,如果解析其余部分不是增加的序列,digit+=1,转到2,否则你找到了差距。
  6. 如果它比最后解析的数字高1,则转到3.
  7. digit+=1,转到2.(我不确定这种情况是否会发生)
  8. 示例:
    给出:“131416”。
    1. digits = 1
    2.解析'1' 3.解析'3' 4.它没有减少
    5.可能找到差距:解析剩下的'1416'失败,因为'1'!='4'    =>数字+ = 1(数字= 2)转到2
    2.解析'13' 3.解析'14' 4.它没有减少
    5.它比最后解析的(13)更高2 6.它高1(14 = 13 + 1)=>转到3
    3.解析'16' 4.它没有减少
    5.可能找到差距:解析其余的''通过因为没有更多的解析,
       =>发现了噱头:'15'是缺失的数字

答案 3 :(得分:0)

这是一个可以在LINQPad中查看的有效C#解决方案:

void Main()
{
    FindMissingNumberInString("9899100101103104105").Dump("Should be 102");
    FindMissingNumberInString("78910121314").Dump("Should be 11");
    FindMissingNumberInString("99899910011002").Dump("Should be 1000");

    // will throw InvalidOperationException, we're missing both 1000 and 1002
    FindMissingNumberInString("99899910011003");
}

public static int FindMissingNumberInString(string s)
{
    for (int digits = 1; digits < 4; digits++)
    {
        int[] numbers = GetNumbersFromString(s, digits);
        int result;
        if (FindMissingNumber(numbers, out result))
            return result;
    }
    throw new InvalidOperationException("Unable to determine the missing number fro '" + s + "'");
}

public static int[] GetNumbersFromString(string s, int digits)
{
    var result = new List<int>();
    int index = digits;
    int number = int.Parse(s.Substring(0, digits));
    result.Add(number);

    while (index < s.Length)
    {
        string part;
        number++;
        digits = number.ToString().Length;
        if (s.Length - index < digits)
            part = s.Substring(index);
        else
            part = s.Substring(index, digits);
        result.Add(int.Parse(part));
        index += digits;
    }
    return result.ToArray();
}

public static bool FindMissingNumber(int[] numbers, out int missingNumber)
{
    missingNumber = 0;

    int? found = null;
    for (int index = 1; index < numbers.Length; index++)
    {
        switch (numbers[index] - numbers[index - 1])
        {
            case 1:
                // sequence continuing OK
                break;

            case 2:
                // gap we expect to occur once
                if (found == null)
                    found = numbers[index] - 1;
                else
                {
                    // occured twice
                    return false;
                }
                break;

            default:
                // not the right sequence
                return false;
        }
    }

    if (found.HasValue)
    {
        missingNumber = found.Value;
        return true;
    }

    return false;
}

这可能会大大简化,但在探索性编码过程中,我喜欢编写清晰易懂的代码,而不是尝试用尽可能少的代码或尽可能快的速度编写代码。