您的位置:首页 > 其它

24点游戏 程序(二)

2012-02-26 14:05 417 查看
前面既然确定了后缀表达式的序列。

那就可以开始遍历了。

#include <iostream>
#include <stack>
#include <algorithm>
#include <string>
#include <cmath>
#include <time.h>
using namespace std;

struct TOperData
{
int operType;
double data;
};

//检查计算的参数是否合法,也可以用于过滤一些重复的表达式
bool checkjisuan(double a, double b, int op)
{
//处理除以0的情况
if (op == '/' && b < 1e-6 && b > -1e-6)
return false;
return true;
}

//求值
double jisuan(double a, double b, int op)
{
switch(op)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
default:
return -1;
}
}
//计算表达式的值
double process(TOperData data[])
{
int len = 7;
stack<TOperData> suffix;

for (int i = 0; i < len; i++)
{
if (data[i].operType == 0)
{
suffix.push(data[i]);
}
else if (data[i].operType > 0)
{
if (suffix.empty())
return false;
if (suffix.top().operType == 0)
{
double a = suffix.top().data;
suffix.pop();
if (!suffix.empty() && suffix.top().operType == 0)
{
double b = suffix.top().data;
suffix.pop();
if (!checkjisuan(b,a,data[i].operType)) return -1;
double c = jisuan(b,a,data[i].operType);
TOperData opdata;
opdata.operType = 0;
opdata.data = c;
suffix.push(opdata);
}
else
{
return -1;
}
}
else
{
return -1;
}
}
}
if (suffix.empty()) return -1;
if (suffix.top().operType == 0)
{
double r = suffix.top().data;
suffix.pop();
if (suffix.empty()) return r;
}
return -1;
}

//打印成功的结果
void printResult(TOperData computeData[])
{
for (int i = 0; i < 7; i++)
{
if (computeData[i].operType == 0)
{
cout<<computeData[i].data<<" ";
}
else
{
cout<<(char)computeData[i].operType<<" ";
}
}
cout<<endl;
}

int start(double data[])
{
int shunxu[][7] = {	1,1,1,1,2,2,2 ,
1,1,1,2,1,2,2 ,
1,1,1,2,2,1,2 ,
1,1,2,1,1,2,2 ,
1,1,2,1,2,1,2
};
int operAll[] = {'+','-','*','/'};
TOperData computeData[7];
double copydata[4];
copydata[0] = data[0];
copydata[1] = data[1];
copydata[2] = data[2];
copydata[3] = data[3];
//5个后缀表达式遍历
for (int m = 0; m < 5; m++)
{
do
{
int oper[3];
for(int n = 0; n < 4; n++)
{
oper[0] = operAll
;
for(int nn = 0; nn < 4; nn++)
{
oper[1] = operAll[nn];
for(int nnn = 0; nnn < 4; nnn++)
{
oper[2] = operAll[nnn];
int j = 0;
int k = 0;
for (int i = 0; i < 7; i++)
{
if (shunxu[m][i] == 1)
{
computeData[i].operType = 0;
computeData[i].data = data[j++];
}
else if (shunxu[m][i] == 2)
{
computeData[i].operType = oper[k++];
}
}
double r = process(computeData);
if (r-24 > -1e-6 && r-24 < 1e-6)
{
cout<<copydata[0]<<" "<<copydata[1]<<" "<<copydata[2]<<" "<<copydata[3]<<",";
printResult(computeData);
//return 1;如果只要求一个结果,这个地方就可以返回了
}
}
}
}
}
while ( next_permutation (data,data+4) );
}
return 0;
}

int main(void)
{
long beginTime =clock();//获得开始时间,单位为毫秒
double data[4];
for (int i = 1; i< 14; i++)
{
data[0] = i;
for (int ii = i; ii< 14; ii++)
{
data[1] = ii;
for (int iii = ii; iii< 14; iii++)
{
data[2] = iii;
for (int iiii = iii; iiii< 14; iiii++)
{
data[3] = iiii;
double copydata[4];
copydata[0] = data[0];
copydata[1] = data[1];
copydata[2] = data[2];
copydata[3] = data[3];
start(copydata);
}
}
}
}
long endTime=clock();//获得结束时间
cout<<"time:"<<endTime-beginTime<<endl;
return 0;
}


这样执行得到50000个结果,耗时30s左右



仔细看这些结果,可以发现有一些重复的。

接下来要简单消除一下重复,以及为了结果更直观,把后缀表达式改成中缀表达式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: