網(wǎng)上有很多關(guān)于pos機(jī)推廣語言,關(guān)于漢諾塔問題C語言的知識,也有很多人為大家解答關(guān)于pos機(jī)推廣語言的問題,今天pos機(jī)之家(www.rcqwhg.com)為大家整理了關(guān)于這方面的知識,讓我們一起來看下吧!
本文目錄一覽:
pos機(jī)推廣語言
寫在前面:我是菜雞,文章都是主觀的我認(rèn)為,不保證正確性,我是菜雞,求輕噴
漢諾塔問題:相傳在古印度圣廟中,有一種被稱為漢諾塔(Hanoi)的游戲。該游戲是在一塊銅板裝置上,有三根桿(編號A、B、C),在A桿自下而上、由大到小按順序放置64個金盤(如圖1)。游戲的目標(biāo):把A桿上的金盤全部移到C桿上,并仍保持原有順序疊好。操作規(guī)則:每次只能移動一個盤子,并且在移動過程中三根桿上都始終保持大盤在下,小盤在上,操作過程中盤子可以置于A、B、C任一桿上。
好,然后很顯然嘛,我是菜雞,解決不了這個問題。那么去搜答案嘛。一搜就出來了,一大堆,按著幾個推送在前面的進(jìn)去……培訓(xùn)班廣告。行嘛,繼續(xù)再往下找。一個看起來就很厲害的老師開始分析:同學(xué)們,看看漢諾塔問題。剛才我們已經(jīng)進(jìn)行了遞歸的學(xué)習(xí),相信同學(xué)們已經(jīng)熟練掌握了技巧,我們可以把這個問題簡化為三個步驟。
(1)以C盤為中介,從A桿將1至n-1號盤移至B桿;
(2)將A桿中剩下的第n號盤移至C桿;
(3)以A桿為中介;從B桿將1至n-1號盤移至C桿。
說完然后就開始寫代碼了,然后就寫完了,然后就是牛逼牛逼!看的我是一臉懵逼。我接著去搜好幾個,講法完全雷同,但并沒有人仔細(xì)講解到底是怎么實(shí)現(xiàn)的,具體遞歸的步驟演示,就是強(qiáng)調(diào)上面三個步驟,然后代碼就出來了。我的感受,就是仿佛人類從原始社會一躍到了登上火星。以前有人調(diào)侃說,數(shù)學(xué)課上彎腰撿起來一支筆,從此一個學(xué)期的數(shù)學(xué)課都在坐飛機(jī)——我當(dāng)時的內(nèi)心就是這樣,區(qū)別是我連腰都沒有彎,一直死盯著黑板。
void Move(char pos1, char pos2){printf("%c->%c ", pos1, pos2);}
void Hanoi(int n, char pos1, char pos2, char pos3){if (1 == n){Move(pos1, pos3);}else{Hanoi(n - 1, pos1, pos3, pos2);Move(pos1, pos3);Hanoi(n - 1, pos2, pos1, pos3);}}
int main(){int n = 0;char pos1 = 'A';char pos2 = 'B';char pos3 = 'C';Hanoi(1, pos1, pos2, pos3);Hanoi(2, pos1, pos2, pos3);printf("\");Hanoi(3, pos1, pos2, pos3);printf("\");Hanoi(4, pos1, pos2, pos3);printf("\");return 0;}把源碼貼上來,為什么貼,大家懂得都懂哈。不知道直接復(fù)制粘貼好不好用。
然后我研究這玩意研究了半天,當(dāng)然我最后研究得應(yīng)該可以說是七七八八了。天才就略過我吧,可能我是真的蠢。我研究的結(jié)論是,你能搜到的一大半對這個問題的解讀是屬于,老手不用聽一點(diǎn)就會,新手聽不懂一臉茫然。起碼我就是這么覺得:我前幾次看這代碼,連遞歸從哪里進(jìn),從哪里出來都不知道。
言歸正傳(首先你接受我比較蠢的這個設(shè)定,接下來就好看多了):
在開始之前,理解一下大家都強(qiáng)調(diào)的那三個步驟。我覺得那個我還是能理解的,就是把塔分成兩塊嘛,一塊移到B,最下層移到C,再把B的移到C。那么我遇到的第一個問題,拋開遞歸步驟不談——我確實(shí)未能領(lǐng)會,按照別人說的,只是單純重復(fù)強(qiáng)調(diào)的那三個步驟。那開頭或者結(jié)尾,不論算的塔有幾層,都該有一步是完全一樣的,開頭都應(yīng)該是A->B,結(jié)束都該是A->C。但代碼隨便跑一下顯然不是這么回事:
你發(fā)現(xiàn)是交錯著的。這個要解釋起來很簡單,你一塊的時候,直接從A柱就移動到C柱了,而你兩塊的時候必須經(jīng)過B柱的周轉(zhuǎn)。有些人可能會說,三塊也從B柱周轉(zhuǎn)就行啊,三塊的時候若你最上面一塊,移動到B柱,那同樣的步數(shù),你最下面一塊只能放在B柱,而不是C柱上。也就是說,塔層為單數(shù)的時候第一步是A到C,最后一步也是A到C;而雙數(shù)的時候,第一步是A到B,必以B到C收尾。而代碼也是在Hanoi(n - 1, pos1, pos3, pos2)這一步在反復(fù)遞歸中,不停地交換位置,實(shí)現(xiàn)這一點(diǎn)的。
我不知道為什么沒人提這點(diǎn),可能大家都默認(rèn)知道?但是我比較笨,不太理解。第一個寫出代碼的人,應(yīng)該是考慮過這個問題的,而不是單純按著那三個步驟,然后就嘩嘩嘩流暢地寫出來了。很巧妙!
第二個問題就是怎么遞歸的,說得再通俗一點(diǎn),就是程序運(yùn)行的順序是怎么樣的?這個簡單,逐語句調(diào)試,一條條跑。以及它為什么是這個順序。在我沒看到下面這張圖,和另外一篇很角落才現(xiàn)的文章前,我不理解,它的遞歸為什么是這么一個運(yùn)行邏輯。
三塊的示例
下?我們以n=3為例來詳細(xì)地解釋?遍,這?我們需要?到?點(diǎn)棧的概念,簡單說就是每?次遞歸之前程序都會將現(xiàn)在的數(shù)據(jù)儲存在棧中(從下往上存儲),遞歸結(jié)束后會依次從上往下調(diào)出數(shù)據(jù),之后程序就會返回到這個數(shù)據(jù)存儲的地?向后繼續(xù)執(zhí)?,此時棧中的這?條數(shù)據(jù)也會消失。當(dāng)程序執(zhí)?到第?個hanoi函數(shù)時,顯然n!=1,執(zhí)?else的部分,此時hanoi函數(shù)中的變量值為hanoi(3,A,B,C),在執(zhí)?第8?語句之前,?先要將其存放到棧中。經(jīng)過下??的遞歸后,四個值變?yōu)閔anoi(2,A,C,B)。此時棧中的數(shù)據(jù)為
第?次 hanoi(2,A,C,B)上面初始 hanoi(3,A,B,C)下面
再運(yùn)行一次,n為1,執(zhí)行printf的語句。再調(diào)用hanoi2執(zhí)行完消失,然后再是hanoi1執(zhí)行完結(jié)束。也就是有的人解釋說“跳回”,這里為什么跳回的原因。
我再用n=4一步步來走一遍,主函數(shù)開始就不用看了,直接從hanoi開始,主要介紹n值的變化以及程序跑的順序:
這里進(jìn)去的是n=4,if判斷非,執(zhí)行else第一步的hanoi,執(zhí)行完后這里n=3,再回去if判斷,再回第一步hanoi,n=2,再判斷,回來這時候n=1,執(zhí)行Move:
move就上邊那玩意,move執(zhí)行完之后,第一步的hanoi語句就暫告結(jié)束,但它還儲存著n=2、3、4的值。按順序,先從n=2開始。一二三步那里,就繼續(xù)往下走,執(zhí)行第二步的move。第三步,也就是第二次的hanoi,此時n值變?yōu)?,執(zhí)行if的是,也就是move。儲存是第一步的hanoi儲存的(if判斷是非,按順序下來就是第一句hanoi而不是第二句),那么每次還得回到第一步hanoi結(jié)束的位置。這時候n=2的已經(jīng)弄完了,排除出棧,繼續(xù)n=3。執(zhí)行move,再來到第二條hanoi,n值變?yōu)?,判斷失敗再回來,變?yōu)?,執(zhí)行判斷成功后的語句。因?yàn)樯线呥€有一條n值變?yōu)?,沒有處理,因此再回到第一條hanoi的時候,首先調(diào)用它,也就是n值仍然為2。接著move,再走n就變?yōu)?,執(zhí)行if成功。
最復(fù)雜的n=4的時候。首先還是跳回取n=4執(zhí)行move,緊隨其后遍歷第二條hanoi直至n為1,執(zhí)行if成功。n=2再次出現(xiàn)在第一句hanoi完成之后,執(zhí)行move,執(zhí)行第三步后,n變?yōu)?,執(zhí)行if成功后。 n=3再次出現(xiàn)在第一句hanoi完成之后,執(zhí)行move,執(zhí)行第三步后,n變?yōu)?,再判斷一次后,執(zhí)行一次hanoi第一句就if成功。再來一次從第一句hanoi結(jié)束后的n=2,因?yàn)槟闵弦徊絥=3第一次變?yōu)?的時候if是失敗的,它是棧里的最后一個。
敘述可能很復(fù)雜繁瑣,但勝在一步步地說。反正我寫完是印象深刻了。目的也達(dá)到了,希望能幫到人,哪怕一兩個也好。
最后說下遞歸,當(dāng)你發(fā)現(xiàn)問題能從一個大問題不斷拆分成兩個時,而拆分的辦法又有跡可循,就是如此。
以上就是關(guān)于pos機(jī)推廣語言,關(guān)于漢諾塔問題C語言的知識,后面我們會繼續(xù)為大家整理關(guān)于pos機(jī)推廣語言的知識,希望能夠幫助到大家!