從石頭剪刀布淺談算法的做用

       剛開始學習C語言的時候,經常聽到前輩說,C語言的核心就是算法。可是對於小白來講,經常一臉懵逼,搞不懂啥叫算法?算法有什麼用?個人if-else語句照樣能夠走天下。可是做爲小白來講雖然不懂可是也不敢問,只能把這個疑問消滅在萌芽狀態。算法

  那麼算法到底意味着什麼?爲何算法如此重要,那麼今天就經過一個簡單的石頭剪刀布的遊戲來粗略的談一下算法的造成緣由和做用?markdown

  好比如今要寫一個兩我的玩石頭剪刀布的程序,要如何實現。對於小白來講,這簡單if-else語句就搞定了。學習

代碼以下:優化

if(本身==石頭 && 對方==石頭) 平局;
else if(本身==石頭 && 對方==剪刀) 本身贏;
else if(本身==石頭 && 對方==布) 對方贏;

if(本身==剪刀 && 對方==石頭) 對方贏;
else if(本身==剪刀 && 對方==剪刀) 平局;
else if(本身==剪刀 && 對方==布) 本身贏;

if(本身==布 && 對方==石頭) 本身贏;
else if(本身==布 && 對方==剪刀) 對方贏;
else if(本身==布 && 對方==布) 平局;
複製代碼

固然這個代碼還能夠優化一下spa

if(本身==石頭)
{
    if(對方==石頭) 平局;
    else if(對方==剪刀) 本身贏;
    else if(對方==布) 對方贏;
}

if(本身==剪刀)
{
    if(對方==石頭) 對方贏;
    else if(對方==剪刀) 平局;
    else if(對方==布) 本身贏;
}

if(本身==布)
{
    if(對方==石頭) 本身贏;
    else if(對方==剪刀) 對方贏;
    else if(對方==布) 平局;
}
複製代碼

    這個結構看起來更加清晰明瞭,也可使用switch語句來實現,無論用什麼語句來實現,這裏核心思想就是將全部的狀況列出來,而後逐一去判斷,沒有任何算法可言。若是按照這個思路去實現,那麼假如要比較的是幾十種狀況,難道還能逐一去列舉判斷嗎?那幾千種幾萬種比較呢?光列舉出全部的狀況估計都要累死了。code

    那麼這個時候就須要用一個方法來抽象這種狀況,讓程序判斷起來更加方便。邏輯上更容易實現。石頭剪刀布的核心相似於比較大小,那麼能不能將石頭剪刀布轉換爲數字大小的比較。orm

   這裏假設 石頭 = 3  剪刀 = 2 布 = 1 ,而後將石頭剪刀布的邏輯轉換爲 數字  石頭 >  剪刀  對應 3 > 2,  剪刀 > 布 對應  2 > 1, 布 > 石頭 對應 1 > 3, 顯然前兩個邏輯成立,最後一個邏輯不成立,遊戲

那麼就不能直接經過比較大小來判斷,經過觀察發現,凡是邏輯成立的兩個數字之間相差1,最後一個邏輯不成立,數字之間相差2。那麼是否能夠將比較大小轉換爲數學的減法運算。數學

當本身的數字 - 對方的數字 結果等於1時,本身獲勝。結果等於2時,對方獲勝,結果等於0時,平局。這樣分析以後貌似能夠實現。那麼將全部的狀況轉換爲用減法來實現時時代碼邏輯以下:it

石頭 = 3  剪刀 = 2 布 = 1 

if(本身==石頭 && 對方==石頭) 平局;          對應算式爲 3-3 = 0
else if(本身==石頭 && 對方==剪刀) 本身贏;    對應算式爲 3-1 = 1
else if(本身==石頭 && 對方==布) 對方贏;      對應算式爲 3-1 = 2

if(本身==剪刀 && 對方==石頭) 對方贏;        對應算式爲 2-3 = -1
else if(本身==剪刀 && 對方==剪刀) 平局;      對應算式爲 2-2 = 0
else if(本身==剪刀 && 對方==布) 本身贏;      對應算式爲 2-1 = 1

if(本身==布 && 對方==石頭) 本身贏;         對應算式爲 1-3 = -2
else if(本身==布 && 對方==剪刀) 對方贏;     對應算式爲 1-2 = -1
else if(本身==布 && 對方==布) 平局;        對應算式爲 1-1 = 0
複製代碼

經過對比算式的結果能夠發現   當本身 - 對方的結果等於0時爲平局,本身 - 對方的結果爲1或者-2時 本身贏。當本身 - 對方的結果爲2或者-1 時對方的贏。

那個根據這個就能夠將上面的算法抽象爲3類,本身贏,平局,對方贏。這樣代碼實現起來就更加簡潔了,實現方法以下

/* 石頭 = 3  剪刀 = 2 布 = 1 */

結果 =  本身 - 對方;

if(結果 == 0)  平局;
else if(結果 == 1 || 結果 == -2) 本身贏;
else if(結果 == -1 || 結果 == 2) 對方贏 ;
複製代碼

這樣直接經過3條語句就直接實現了石頭剪刀布的邏輯判斷,並且程序寫起來更加的簡潔,邏輯更加清晰。可見在代碼邏輯實現的過程當中有了算法的加持,程序發生了質的變化。

一個簡單的例子就能夠看出算法在程序中舉足輕重的做用,因此說寫代碼不只僅上是邏輯上把功能實現了就能夠了,但實現功能的同時,還須要考慮效率的問題。

下面在舉一個簡單的例子來演示一下算法的應用。

      這裏有15瓶水,其中有1瓶是劇毒,小白鼠只要喝上一滴,過一天後就會死亡,那麼如何用最少的小白鼠,在最短的時間內找出哪一個瓶子裏面有毒藥?

      直接能夠想到的辦法就是找15只小白鼠,一隻小白鼠喝對應編號的一瓶水就行。這種方法雖然最簡單,可是浪費的小白鼠倒是最多的。確定不是最好的辦法。可讓一個小白鼠喝好幾個瓶子的水,而後經過交叉排除的方法篩選出來那個瓶子有毒。這個能夠經過二進制的思惟來實現。

     首先將這15個瓶子標上號碼,從1到15,而後將這些數字轉換爲二進制。

                                   

能夠看到15個瓶子,經過二進制數表示的話,須要4位,那麼1只小白鼠表明1位的話,用4個小白鼠就能夠表示1---15,順着這個思路就能夠經過一個小白鼠喝好幾瓶混合的水,來篩選出有毒的那瓶水。

將15瓶水分爲4組,第一組黃色的就是二進制數最低位爲1的編號,也就是將二進制字最右邊那個數字爲1對應的那瓶水混合在一塊兒,而後將混合後的水給第1只小白鼠喝。

至關於第一隻小白鼠喝的是一、三、五、七、九、十一、1三、15這幾個編號混合起來的水,按照一樣的方法,將二進制數字右邊第二位爲1的水混合起來,給第二隻小白鼠喝。

至關於第二隻小白鼠喝的是二、三、六、七、十、十一、1四、15這幾個編號混合起來的水,按照一樣的方法,將二進制數字左邊第二位爲1的水混合起來,給第三隻小白鼠喝。

至關於第三隻小白鼠喝的是四、五、六、七、十二、1三、1四、15這幾個編號混合起來的水,按照一樣的方法,將二進制數字最左邊爲1的水混合起來,給第四隻小白鼠喝。

至關於第四隻小白鼠喝的是八、九、十、十一、十二、1三、1四、15這幾個編號混合起來的水。

第一天將這些混合起來的水,分別給四隻小白鼠喝,而後次日觀察結果就能夠知道哪瓶水有毒了?

假如次日,第一隻和第三隻小白鼠死了,說明對應的二進制數字第一位和第三位是1,對應的二進制數字就是 0101,這樣就能夠根據二進制數直接算出來有毒的是5號瓶。

假如次日,一、三、4只小白鼠死了,說明對應的二進制數字就是1101,那麼瓶子對應的編號就是13號。

這樣用4只小白鼠,在次日就能夠找出有毒的那瓶水了。

經過轉換一個思惟,用另外一種方法去解決問題,就能夠輕鬆的將複雜的問題簡單化,能夠看出一個好多算法在實際應用中能夠起到一兩撥千金的做用。

經過上面的兩個簡單的例子,我想如今應該能夠明白了,在程序中爲何要研究算法,算法爲何對於程序來講這麼重要了! 

相關文章
相關標籤/搜索