一個翻拍過程 翻排使用隊列

本週四同事分享了一個思惟訓練的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

相關文章
相關標籤/搜索