您的位置:首页 > 其它

一个类24点问题算法实现

2012-04-26 11:26 525 查看
问题描述:
  在game.in中给定任意5个整数和期望数EXPECTION_VAL,使用+ - * /进行对这5个数进行运算,每个运算操作只能使用一次,()可以使用无数次。
  输出一个计算结果或者证明无合适解。

算法思路:
  一个基本的解析算式是exp = (exp | num ) op (exp | num)
  接下来使用动态规划进行计算就行了,将最近操作的两个数加入到算子集合重新计算,如此递归,直至找到解或者计算完所有的可能。
  对于calculate函数相关的因素包括(算子集合,操作子集合)。
  递归边界应该是算子集合数目为2并且操作子数目为1。

说明:
  本程序的实现没有怎么优化,有很多冗余可以使用记录exp算式的方法进行剔除,  


/*******************************************************************************
* created:2012/04/26
* created:2012-4-26   11:04
* file base:main
* file ext:cpp
* author:xiaoyang hityixiaoyang@gmail.com
********************************************************************************
* 描述:
* 在game.in中给定任意5个整数和期望数EXPECTION_VAL,使用+ - * /进行对这5
* 个数进行运算,每个运算操作只能使用一次,()可以使用无数次。
* 输出一个计算结果或者证明无合适解。
********************************************************************************/
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
#include <string>
#include <stack>

using namespace std;

long CalCount = 0;

const char* INPUT_FILE  = "game.in";
const char* OUTPUT_FILE = "game.out";
const char* RES_FILE = "game.res";
const int NUMBER_COUNT  = 5;
//const
int EXPECTION_VAL = 0;

vector<int> Nums;
//vector<int> OrgNums;
vector<char> Ops;
//vector<char> OrgOps;
ofstream fout;
ofstream fres;
typedef struct exp {
int num1;
int num2;
char op;
} Exp;
stack<exp> ResStr;

void PrintRes()
{
fout<< "--------------------" <<endl;
fres<< "--------------------" <<endl;
while (!ResStr.empty()) {
fout << ResStr.top().num1  << ","  << ResStr.top().num2 << "," << ResStr.top().op << endl;
fres << ResStr.top().num1  << ","  << ResStr.top().num2 << "," << ResStr.top().op << endl;
ResStr.pop();
}
fout<< "--------------------\nend!" <<endl;
fres <<endl;
}

void AddRes(int num1,int num2, char op)
{
Exp tmpExp;
tmpExp.num1 = num1;
tmpExp.num2 = num2;
tmpExp.op = op;
ResStr.push(tmpExp);
}

void Config()
{
int tmp = 0;
ifstream fin(INPUT_FILE);
if (fin.eof()) {
exit(-2);
}

for (int i = 0; i < NUMBER_COUNT; i++) {
fin >> tmp;
Nums.push_back(tmp);
}

fin >> EXPECTION_VAL;
Ops.push_back('+');
Ops.push_back('-');
Ops.push_back('*');
Ops.push_back('/');

fout.open(OUTPUT_FILE);
fout << "steps:"<<endl;

fres.open(RES_FILE);
fres << "steps:"<<endl;
}

/*
* ret:
*        -1,calculate failed
*        0,success
*/
int Calculate(vector<int>& iNums,vector<char>& iOps)
{
//unsigned int i=0, j=0, k=0;
int newNum1 = 0, newNum2 = 0;
vector<char>::iterator vc_it;

/**/
if ((iOps.size() == 1) || (iNums.size() == 2)) {
int res = -1;
if (iOps[0] == '+') {
res = iNums[0] + iNums[1];
/*(n,n,op) res:*/
fout << "(" << iNums[0] << "," << iNums[1] << "," << iOps[0] << ") res:" << res << endl;
if(res == EXPECTION_VAL) {
goto suc;
} else {
goto fail;
}
} else if (iOps[0] == '-') {
res = iNums[0] - iNums[1];
/*(n,n,op) res:*/
fout << "(" << iNums[0] << "," << iNums[1] << "," << iOps[0] << ") res:" << res << endl;
if(res == EXPECTION_VAL) {
goto suc;
} else {
fout << "failed:recalculate!" << endl;
}

res = iNums[1] - iNums[0];
/*(n,n,op) res:*/
fout << "(" << iNums[1] << "," << iNums[0] << "," << iOps[0] << ") res:" << res << endl;
if(res == EXPECTION_VAL) {
goto suc;
} else {
goto fail;
}
} else if (iOps[0] == '*') {
res = iNums[0] * iNums[1];
/*(n,n,op) res:*/
fout << "(" << iNums[0] << "," << iNums[1] << "," << iOps[0] << ") res:" << res << endl;
if(res == EXPECTION_VAL) {
goto suc;
} else {
goto fail;
}
} else if (iOps[0] == '/') {
if((iNums[0] == 0) | (iNums[1] == 0)) {
res = 0;
fout << "(" << iNums[0] << "," << iNums[1] << "," << iOps[0] << ") res:" << res << endl;
if(res == EXPECTION_VAL) {
goto suc;
} else {
goto fail;
}
} else {
res = (int)(iNums[0] / iNums[1]);
fout << "(" << iNums[0] << "," << iNums[1] << "," << iOps[0] << ") res:" << res << endl;
if(res == EXPECTION_VAL) {
goto suc;
} else {
fout << "failed:recalculate!" << endl;
}

res = (int)(iNums[1] / iNums[0]);
fout << "(" << iNums[1] << "," << iNums[0] << "," << iOps[0] << ") res:" << res << endl;
if(res == EXPECTION_VAL) {
goto suc;
} else {
goto fail;
}
}
} else {
cout << "error: unknown exception @"<< __LINE__ << endl;
return -1;
}

suc:
CalCount++;
return 0;
fail:
fout << "failed:recalculate!" << endl;
CalCount++;
return -1;
}

/*it's important!used for resume stack*/
vector<int> OrgNums(iNums);
vector<char> OrgOps(iOps);
/*choose 2 numbers,calculate them*/
for (unsigned int i = 0; i < OrgNums.size(); i++) {
newNum1 = iNums.at(i);
iNums.erase(iNums.begin()+i);

/*it's important!used for resume stack*/
vector<int> OrgNums2(iNums);
for(unsigned int j = 0; j < iNums.size(); j++) {
newNum2 = iNums.at(j);
iNums.erase(iNums.begin()+j);

fout << "\t" << newNum1 << "," << newNum2 <<endl;
/*+*/
vc_it = find(iOps.begin(),iOps.end(),'+');
if(vc_it != iOps.end()) {
fout << "(" << newNum1 << "," << newNum2 << ",+)" << endl;
iNums.push_back(newNum1+newNum2);
iOps.erase(vc_it);
if (Calculate(iNums,iOps) == 0) {
AddRes(newNum1,newNum2,'+');
cout << "success:got it!" << endl;
fout << "success:got it!" << endl;
return 0;
} else {
iNums.pop_back();
iOps.clear();
iOps = OrgOps;
}
}

/*-*/
vc_it = find(iOps.begin(),iOps.end(),'-');
if(vc_it != iOps.end()) {
fout << "(" << newNum1 << "," << newNum2 << ",-)" << endl;
iNums.push_back(newNum1-newNum2);
iOps.erase(vc_it);
if (Calculate(iNums,iOps) == 0) {
AddRes(newNum1,newNum2,'-');
cout << "success:got it!" << endl;
fout << "success:got it!" << endl;
return 0;
} else {
iNums.pop_back();
iOps.clear();
iOps = OrgOps;
}

fout << "(" << newNum2 << "," << newNum1 << ",-)" << endl;
vc_it = find(iOps.begin(),iOps.end(),'-');
if(vc_it != iOps.end()) {
iNums.push_back(newNum2-newNum1);
iOps.erase(vc_it);
if (Calculate(iNums,iOps) == 0) {
AddRes(newNum2,newNum1,'-');
cout << "success:got it!" << endl;
fout << "success:got it!" << endl;
return 0;
} else {
iNums.pop_back();
iOps.clear();
iOps = OrgOps;
}
}
}

/***/
vc_it = find(iOps.begin(),iOps.end(),'*');
if(vc_it != iOps.end()) {
fout << "(" << newNum1 << "," << newNum2 << ",*)" << endl;
iNums.push_back(newNum1*newNum2);
iOps.erase(vc_it);
if (Calculate(iNums,iOps) == 0) {
AddRes(newNum1,newNum2,'*');
cout << "success:got it!" << endl;
fout << "success:got it!" << endl;
return 0;
} else {
iNums.pop_back();
iOps.clear();
iOps = OrgOps;
}
}

/*/*/
vc_it = find(iOps.begin(),iOps.end(),'/');
if(vc_it != iOps.end()) {
if (newNum2 != 0) {
fout << "(" << newNum1 << "," << newNum2 << ",/)" << endl;
if (newNum1%newNum2 == 0) {
iNums.push_back((int)(newNum1/newNum2));
iOps.erase(vc_it);
if (Calculate(iNums,iOps) == 0) {
AddRes(newNum1,newNum2,'/');
cout << "success:got it!" << endl;
fout << "success:got it!" << endl;
return 0;
} else {
iNums.pop_back();
iOps.clear();
iOps = OrgOps;
}
}
}

vc_it = find(iOps.begin(),iOps.end(),'/');
if(vc_it != iOps.end()) {
if (newNum1 != 0) {
if (newNum2%newNum1 == 0) {
fout << "(" << newNum2 << "," << newNum1 << ",/)" << endl;
iNums.push_back((int)(newNum2/newNum1));
iOps.erase(vc_it);
if (Calculate(iNums,iOps) == 0) {
AddRes(newNum2,newNum1,'/');
cout << "success:got it!" << endl;
fout << "success:got it!" << endl;
return 0;
} else {
iNums.pop_back();
iOps.clear();
iOps = OrgOps;
}
}
}
}
}

iNums.clear();
iNums = OrgNums2;
}

iNums.clear();
iNums = OrgNums;
}

//iOps = OrgOps;
/*no res*/
cout << "no answer!" << endl;
fout << "no answer!" << endl;

return -1;
}

int main(void)
{
Config();
Calculate(Nums,Ops);
PrintRes();
cout << "Calculate times:" << CalCount << endl;
fout << "Calculate times:" << CalCount << endl;
fres << "Calculate times:" << CalCount << endl;
fout.flush();
fres.flush();
getchar();
return 0;
}


使用这个代码前需要先家建立1个输入文件game.in,并在文件里输入5个算子和一个期望值。

输出结果会在game.res、 game.out文件中显示
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐