在数字序列中找到第一个间隙的索引

时间:2019-05-15 20:56:27

标签: c#

我有问题。有点难以解释,但我将尝试。我有几个按钮,我想给出一个顺序。我用按钮和SequenceNum创建了一个字典。现在,当我在顺序选择屏幕中时,我可以单击一个按钮并为其指定一个数字。现在,我有了这段代码来获取下一个最高的数字:

foreach (KeyValuePair<string, SelectedHexagonRegistryObject> row in SelectedHexagonRegistry.ToList())
{
    if (row.Value.SequenceNum >= NextSequenceNum)
    {
        NextSequenceNum = row.Value.SequenceNum + 1;
    }
}

现在,SequenceNum总是会得到下一个最高的数字,但这是有问题的。例如,当我给6个按钮一个序列号,然后再次单击3时,它将重置。那应该发生,但是例如当我想交换数字时,我还要单击带有SequenceNum 4的按钮。有2个没有序列号的按钮。如果我单击两个没有序列号的按钮之一。下一个数字是7。但是问题是存在一个空格,因为数字3和4被重置,所以我想成为下一个最小数字的空格。我该如何创建类似的东西?

示例:
我有6个按钮,我想提供一个序列号。
当我单击第一个按钮时,它将获得SequenceNum 1
然后,当我单击其余部分时,它将获得给定的最高数字+1。
最后,我有6个按钮,其序列号从1到6。
例如,当我再次单击SequenceNum = 4的按钮时,我可以将SequenceNum取消设置为0(等于null)。
现在,当我再次单击同一按钮时,我希望它获取我创建的间隙的编号,即SequenceNum4。
现在的问题是它得到7,因为它取最高的+1。
我需要代码来填补空白,我似乎无法弄清楚如何做到这一点!

2 个答案:

答案 0 :(得分:1)

除非我没有记错,否则类似的事情应该起作用:

static int GetNextSequenceNo(Dictionary<string, SelectedHexagonRegistryObject> registry)
{
    // order the values ascending
    var vals = registry.Values.OrderBy(s => s.SequenceNum).ToList();

    // find the first value where .SequenceNum is different from (idx + 1)
    var firstGap = vals.TakeWhile((s, idx) => s.SequenceNum == idx + 1).Count();

    // take the sequenceNum from the previous item and increment
    if (firstGap > 0)
        return vals[firstGap - 1].SequenceNum + 1;
    else
        return 1;            
}

答案 1 :(得分:1)

通常,如果您有一个整数列表,并且想要查找下一个最低的可用数字,则可以对它们进行排序(如果尚未排序),然后一次遍历列表,将当前项目到下一个项目。一旦找到下一项大于当前项大于1的项,您就会发现一个空白并可以返回currentItem + 1

如果您到达列表的末尾,则只需返回下一个数字。例如:

private static int GetNextAvailableNumber(IReadOnlyCollection<int> numberSequence)
{
    // If the list is null or empty, return the first number (this uses 1, modify as needed)
    if (numberSequence == null || !numberSequence.Any()) return 1;

    var orderedNumbers = numberSequence.OrderBy(n => n).ToList();

    for (var i = 0; i < orderedNumbers.Count - 1; i++)
    {
        var thisNumber = orderedNumbers[i];
        var nextNumber = orderedNumbers[i + 1];

        if (nextNumber - thisNumber > 1) return thisNumber + 1;
    }

    return orderedNumbers.Last() + 1;
}