本週四同事分享了一個思惟訓練的PPT,裏面有一個關於翻牌的題目,題目大體是:拿出從A到10的10張撲克牌,背面朝上摞在一塊兒。首先把最上面的一張挪到下面,掀開新出現的一張牌是A,取出,再挪一張牌到下面,翻一張是2,依次類推,能夠有順序地翻出A到10的牌來。請問這10張牌最初是怎麼排列的?看完這個題目,我當時說能夠用一個算法實現。算法
次日6點多醒來就一直在想這個問題,開始的時候想用遞歸實現,最後發現有點複雜,本身實現不了,而後想用數組實現,想法大體是這樣的,先將這N個數存到數組中,而後將第一張插到最後面,第二張爲A,以此類推,將每張牌通過的索引都記下來,由於每張牌最後是幾是知道的,而後反推出1~N張牌是多少,可是發現記錄牌通過的索引有點麻煩,效率也不高,記錄的數組的第一個元素即爲所求。數組
早上到了公司一邊幹活,一邊實現這個算法,從題目能夠很容易看出奇數位一次爲1~N/2,剩下的就是求偶數位的值,立刻寫了個算法,運行是發現有的結果是正確的,大部分是錯的,因而寫了個測試方法,測試方法就很簡單了,這個方法只用模擬翻牌的過程,而後輸出的結果爲1~N就是正確的,不然就是錯誤的。經測試發現個人算法思路徹底是錯誤的,可是經過這個測試算法,我發現了可以正確實現這個題目的方法。這個題目其實不是一個遞歸的過程,而是一個進棧出棧的過程,奇數位進棧,偶數位出棧。咱們知道最後的結果,把每張牌當作一個對象,就是進棧出棧都是以引用的方式,翻牌完成後,按順序將它們的值一次賦值爲1~N,那麼咱們也就知道開始的牌的順序了,就這麼簡單,思路就這麼簡單,實現起來也就很快,因而立刻實現了一個粗糙算法,最後用一個Window Form實現了,發給了同事看看,爲了讓你們能看得清楚,記錄了翻牌的過程,固然要記錄過程也是很簡單的。ide
代碼真的很簡單,將每張牌當作一個對象,這樣就不用記錄牌通過的過程,引用類型嗎!建立的對象的個數爲N,過程也是線性的,不會有性能問題。性能
主要代碼以下(代碼很粗糙,但思路簡單清晰,咱們知道就是對的),源碼下載測試
//將牌定義成對象 public class Card { public int Value=0 ; public override string ToString() { return Value.ToString(); } } //測試算法,記錄了翻牌過程 static List<string> TestResult(Card[] arr) { if (arr == null) { throw new Exception("參數異常"); } int len = arr.Length; Queue<Card> queue = new Queue<Card>(len); foreach (Card i in arr) { queue.Enqueue(i); } List<string> list = new List<string>(len); StringBuilder sb = new StringBuilder(); for (int i = 0; i < len; i++) { list.Add(GetItem(sb.ToString(),queue)); Card cur = queue.Dequeue(); queue.Enqueue(cur); sb.Append(queue.Dequeue().ToString().PadRight(3,' ')+" "); } return list; } static string GetItem(string s,Queue<Card> queue) { StringBuilder sb = new StringBuilder(s); foreach (var item in queue) { sb.Append(item.ToString().PadRight(3, ' ') + " "); } return sb.ToString(); } //實現翻牌的算法 static Card[] TestArr(int size) { Card[] arr = new Card[size]; for (int i = 0; i < size; i++) { arr[i] = new Card(); } int len = arr.Length; Queue<Card> queue = new Queue<Card>(len); foreach (Card i in arr) { queue.Enqueue(i); } for (int i = 1; i <= len; i++) { Card cur = queue.Dequeue(); queue.Enqueue(cur); cur = queue.Dequeue(); cur.Value = i; } return arr; }
幾個截圖,若是題目我說得不清楚,下面幾張圖應該可讓你們看得更明白ui