比较环形缓冲区

时间:2015-12-11 14:16:20

标签: c#

我需要检查例如3,3,3,2,2,3的特定数字序列的接收,但是这个重复序列可以从不同的位置开始,例如3,3,3,3,2, 2

我创建了一个环形缓冲区,用于存储收到的数字并与所有可能的序列进行比较

class MFMSequence {
    int _index = 0;
    int[] _buffer = new int[6];
    public void add(int value) {
        _buffer[_index] = value;
        _index = (_index + 1) % 6;
    }
    public bool is4e() {
        return (_buffer.SequenceEqual(new int[] { 3, 3, 3, 2, 2, 3 }) ||
                _buffer.SequenceEqual(new int[] { 3, 3, 3, 3, 2, 2 }) ||
                _buffer.SequenceEqual(new int[] { 2, 3, 3, 3, 3, 2 }) ||
                _buffer.SequenceEqual(new int[] { 2, 2, 3, 3, 3, 3 }) ||
                _buffer.SequenceEqual(new int[] { 3, 2, 2, 3, 3, 3 }) ||
                _buffer.SequenceEqual(new int[] { 3, 3, 2, 2, 3, 3 }));
    }
    public bool is00() {
        return (_buffer.SequenceEqual(new int[] { 2, 2, 2, 2, 2, 2 }));
    }
}

这很有效,但我发现它太丑了!关于如何更优雅地编码的任何想法

3 个答案:

答案 0 :(得分:0)

你可以试试这个:

private bool CheckIt(int[] checkFor, int[] have)
{
    return Enumerable.Range(0, checkFor.Length).Any(i =>
        checkFor.Concat(checkFor).Skip(i).Take(have.Length).SequenceEqual(have)
    );
}

并非完全“漂亮”,但它是一个快速的模型,我确信有很多改进。也适用于任意数量的项目。用法:

var checkFor = new int[] { 3,3,3,2,2,3 };
var have = new int[] { 3,2,2,3,3,3 };
var result = CheckIt(checkFor, have);

答案 1 :(得分:0)

您可以编写一个循环来比较所有可能的序列,然后至少它会扩展到任意数量的项目而不必更改代码:

public static bool RingBufferContains(int[] buffer, int[] target)
{
    if (buffer == null || target == null || buffer.Length != target.Length)
        throw new InvalidOperationException("buffer and target must be non-null and the same length.");

    int n = buffer.Length;

    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            if (buffer[(i+j)%n] != target[j])
                break;

            if (j == n - 1)
                return true;
        }
    }

    return false;
}

这是一个O(N ^ 2)解决方案,就像你的一样。

测试代码:

int[] buffer = { 3, 2, 2, 3, 3, 3 };
int[] target = { 3, 3, 3, 2, 2, 3 };
Console.WriteLine(RingBufferContains(buffer, target));

答案 2 :(得分:0)

我认为Rob和Matthew Watson解决方案比硬编码所有可能性要好得多。马修的代码更加优化,但Rob看起来更漂亮。如果你的序列很小,那么它们都足够好。但是如果你有更多更大的序列,或者如果你想开发一些通用解决方案,你应该优化它 我的想法是将序列的起始位置设置为min或max元素,并仅比较一次序列 如果我们有几个最小或最大元素,我们有几个可能的起始位置,我们需要多次比较。在最坏的情况下,它将是N / 2次(序列{min,min,min,max,max,max})。