2015-12-11 36 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})。