您的位置:首页 > 其它

关于24点问题的算法

2009-03-10 17:15 225 查看
进来在linux下学习C++,用C++写了一个关于24点问题的算法。我个人以为关于这个问题唯一的解决办法就是遍历所有可能性。要穷举所有表达式,我的思路是:

假设只有两个数字,那个两个数字的运算就有六种可能,M+N,M-N,M*N,M/N,N-M,N/M。参加运算的数字大于两个时就让任意两个数字参加运算,结果又放入其他的数字中,再参加运算。因此,我当然就想到了递归。

整个程序的代码如下。

]/*
功能:通过编历得到24问题的所有解法,并且列出how to get 24.
日期:03-10-2009
作者:Handsome Cheung
版权:Handsome Cheung
*/
#include <iostream>
#include <stdlib.h>
#include <sstream>

using namespace std;

float calc(float m,float n,int i);
void solving(float *p,int len);
string num2str(float fnum);         //将float转换为string
static string temp;                 //temp的所用是讲每一次参加运算的表达式记住
static int StaticLen;               //静态长度,因为计算过程中会改变len的值
static string *howto;               //存放计算成功的每一个表达式
static int qty;                     //解法的数量。

int main()
{
qty = 0;
//申请动态空间
int len;
cout<<"enter the lenth"<<endl;
cin>>len;
float *array = new float[len];
if(NULL==array)
{
cout<<"fail to apply space!program will exit."<<endl;
exit(1);
}
//赋值
cout<<"enter every num..."<<endl;
for(int i=0;i<len;i++)
{
cin>>*(array+i);
}
cout<<endl;
StaticLen=len;

//为howto申请动态空间,用于存放每一个表达式
howto = new string[len - 1];
if(NULL==howto)
{
cout<<"fail to apply space!program will exit."<<endl;
exit(1);
}

solving(array,len);

delete[] array;
array=NULL;
delete[] howto;
howto=NULL;

cout<<"There are(is) "<<qty<<" solution(s)"<<endl;
return 0;

}

void solving(float *p,int len)
{
for(int m=1;m<len;m++)
{
for(int n=m+1;n<=len;n++)
{
if(len==2)
{
for(int i=1;i<=6;i++)
{
if(calc(*(p+m-1),*(p+n-1),i)==24.0)
{
*(howto+StaticLen-2)=temp;
qty++;
for(int l=0;l<=StaticLen-2;l++)
{
cout<<*(howto+l)<<endl;
}
cout<<endl;
}
}
}
else
{

for(int i=1;i<=6;i++)
{
// copy the array to a temporary array:tmp[].
int tmplen;
float *Ptmp;
float tmp[len];
Ptmp=tmp;
tmplen=len;
for(int t=0;t<=len;t++)
{
*(tmp+t)=*(p+t);
}

*(Ptmp+m-1)=calc(*(p+m-1),*(p+n-1),i);
*(Ptmp+n-1)=*(Ptmp+tmplen-1);

*(howto+StaticLen-tmplen)=temp;
tmplen--;
solving(Ptmp,tmplen);
tmplen++;
}
}
}
}
}

float calc(float m,float n,int i)
{

switch (i)
{
case 1:
temp=num2str(m) + "+" + num2str(n) + "=" + num2str(m+n);
return m+n;
break;
case 2:
temp=num2str(m) + "-" + num2str(n) + "=" + num2str(m-n);
return m-n;
break;
case 3:
temp=num2str(m) + "*" + num2str(n) + "=" + num2str(m*n);
return m*n;
break;
case 4:
temp=num2str(m) + "/" + num2str(n) + "=" + num2str(m/n);
return m/n;
break;
case 5:
temp=num2str(n) + "-" + num2str(m) + "=" + num2str(n-m);
return n-m;
break;
case 6:
temp=num2str(n) + "/" + num2str(m) + "=" + num2str(n/m);
return n/m;
break;
}
}

string num2str(float fnum)
{
stringstream ss;
ss<<fnum;
return ss.str();
}


为了能计算任意多个数,使用了动态数组。

但是问题是显而易见的:因为使用递归,每调用自身一个就要开辟一个栈;每进行一次运算,不过是否有解,都要改变temp的值,而且每改变一次temp的值就要调用三次num2str()函数。大大降低了程序的效率,当达到6个数字时就非常慢了。虽然可以将num2str()改为内联函数,但其效果也不明显。

待算法改进后尝试作一个桌面接口,学习一下linux下的GNOME编程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: