2015-12-11 103 views
1

我需要检查特定数字序列的接收,例如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 })); 
    } 
} 

环形缓冲区,但我觉得它难看!如何这更优雅

+2

看来您的代码目前正常工作,而您正在寻求改进它。一般来说,这些问题对于这个网站太过分了,但是你可能会在[CodeReview.SE](http://codereview.stackexchange.com/tour)找到更好的运气。请记住阅读[他们的要求](http://codereview.stackexchange.com/help/on-topic),因为它们比这个网站更严格。 – DavidG

+0

听起来类似于[this](http://stackoverflow.com/q/7693992/1997232)(不幸未回答)问题。 – Sinatr

+2

这个问题看起来很适合[Code Review.SE](http://codereview.stackexchange.com/),前提是(a)你希望检查代码的每个方面,而不仅仅是一些, (b)你的代码已经在工作_(c)你正在要求检查_concrete,真正的code_,而不是抽象的设计(不管它是否被表示为代码)。如果您同意所有这些内容,请阅读[主题内容](http://codereview.stackexchange.com/help/on-topic),如果您的问题符合要求,请在此处将其删除并重新发布到CR 。 – Phrancis

回答

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

第一个为'var checkFor = new int [] {3,3,2,3,3}返回fals;'这是错误的。 – Alexander

+0

@亚历山大啊是的,你说得对。将删除该解决方案。谢谢! – Rob

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)); 
+0

这是一个O(N^2)解(原始解也是O(N^2)) – Alexander

+0

@Alexander糟糕,这是一个错字 - 意思是说N^2 –

0

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