關於24點演算法的思想和代碼實現

來源:互聯網
上載者:User

http://chimf.bloghome.cn/posts/49570.html

 

先簡單介紹一下24點遊戲:
給出4個1-9之間的自然數,其中每個數字只能使用一次;任意使用 + - * / ( ) ,構造出一個運算式,使得最終結果為24,這就是常見的算24點的遊戲。比如兩道比較經典的題目:1,5,5,5和3,3,8,8,先自己試試,答案貼在文章最後^_^

此文所貼代碼均為面向過程的C(++)代碼,在VC6下編譯通過。

解決這個問題一般使用窮舉法,即窮舉4個整數所有可能的運算式,然後對錶達式求值。下面的兩種思路(三種演算法)均是基於窮舉法,各有優劣。

第一種思路:
把多元運算轉化為兩元運算,先從四個數中取出兩個數進行運算,然後把運算結果和第三個數進行運算,再把結果與第四個數進行運算。在求運算式的過程中,最難處理的就是對括弧的處理,而這種思路很好的避免了對括弧的處理。基於這種思路有兩種演算法:

第一種演算法:
(1) 將4個整數放入數組中,
(2) 在數組中取兩個數位排列,共有 P(4,2) 種排列。對每一個排列,
(2.1) 對 + - * / 每一個運算子,
(2.1.1) 根據此排列的兩個數字和運算子,計算結果,
(2.1.2) 改表數組:將此排列的兩個數字從數組中去除掉,將 2.1.1 計算的結果放入數組中,
(2.1.3) 對新的數組,重複步驟 2,
(2.1.4) 恢複數組:將此排列的兩個數字加入數組中,將 2.1.1 計算的結果從數組中去除掉。

可以看出,步驟2是一個遞迴函式。當數組中只剩下一個數位時候,這就是運算式的最終結果,此時遞迴結束。

這個是程式碼,原始碼為csdn 演算法論壇前版主海星所作,我修改了部分變數。此程式只能求出第一個解,無法求出全解。

引用內容:(略有修改,VC++ 2005下測試)#include<iostream><br />#include<string><br />#include<cmath><br />using namespace std;<br />const double PRECISION = 1E-6;<br />const int COUNT = 4;<br />const int RESULT = 24;<br />double number[COUNT]; //這裡一定要用double,看看第一題的答案就知道為什麼了<br />string expression[COUNT]; //儲存運算式<br />bool Test(int n){<br />//遞迴結束<br />if(1 == n){<br />if(fabs(number[0]-RESULT)<PRECISION){<br />// 避免輸出前後括弧<br />for (int i = 1; i < expression[0].length() - 1; i++)<br />{<br />cout<<expression[0][i];<br />}<br />cout<<endl;<br />return true;<br />}<br />else<br />return false;<br />}<br />//遞迴過程<br />for(int i=0;i<n;i++){<br />for(int j=i+1;j<n;j++){<br />double a,b;<br />string expa,expb;<br />a=number[i];<br />b=number[j];<br />// 刪除number[j]元素,用number[n-1]填補<br />number[j]=number[n-1];<br />expa=expression[i];<br />expb=expression[j];<br />// 刪除expression[j]元素,用expression[n-1]填補<br />expression[j]=expression[n-1];</p><p>// 加法<br />expression[i]='(' + expa + '+' + expb + ')';<br />number[i]=a+b;<br />if(Test(n-1))<br />return true;<br />//減號有兩種情況,a-b與b-a<br />expression[i]='('+expa+'-'+expb+')';<br />number[i]=a-b;<br />if(Test(n-1))<br />return true;<br />expression[i]='('+expb+'-'+expa+')';<br />number[i]=b-a;<br />if(Test(n-1))<br />return true;<br />// 乘法<br />expression[i]='('+expa+'*'+expb+')';<br />number[i]=a*b;<br />if(Test(n-1))<br />return true;<br />//除法也有兩種情況,a/b與b/a<br />if(b!=0){<br />expression[i]='('+expa+'/'+expb+')';<br />number[i]=a/b;<br />if(Test(n-1))<br />return true;<br />}<br />if(a!=0){<br />expression[i]='('+expb+'/'+expa+')';<br />number[i]=b/a;<br />if(Test(n-1))<br />return true;<br />}<br />//恢複數組<br />number[i]=a;<br />number[j]=b;<br />expression[i]=expa;<br />expression[j]=expb;<br />}<br />}<br />return false;<br />}<br />void main(void){<br />for(int i=0;i<COUNT;i++){<br />char buffer[20];<br />int x;<br />cin >> x;<br />number[i]=x;<br />_itoa_s(x,buffer,10);<br />expression[i]=buffer;<br />}<br />if(Test(COUNT))<br />cout << "Success" << endl;<br />else<br />cout << "Fail" << endl;<br />}<br /> 

 

 

附:

(5-(1/5))*5 = 24

8/(3-(8/3))  = 24

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.