回溯法+栈运算符优先级


题目

1□2□3□4□5□6□7□8□9=110

要求在中间的8个空中填写+,-,或不填。构成的表达式判断是不是正确,正确则输出。。。。

(如果空格的中没有填写符号,则这几个数组成一个新的N位数,比如1□2,可以是1+2,也可以是12)

代码

#include<iostream>
#include<stack>
#include<windows.h>
using namespace std;

int n;//层次
int result = 0;//统计结果
int bestx[9] = {-1};//保存操作符
int a[10] = {1,2,3,4,5,6,7,8,9};//运算数
stack<int> data;//数据栈
stack<int> oper;//运算符栈


int calc(int n)
{

if(n==9){//最后一层运算符计算
while(!oper.empty()){
int b = data.top();//第2个数
data.pop();
int a = data.top();//第1个数
data.pop();
int op = oper.top();
oper.pop();
if(op == 0)//算法
data.push(a+b);
if(op == 1)
data.push(a-b);
}
int result = data.top();//最终结果

if(result == 110){//输出

cout<<'1';
for(int i = 1; i <= 8;i++){
if(bestx[i] == 0 ) cout<<"+";
else if(bestx[i] == 1 ) cout<<"-";
cout<<a[i];
}
cout<<"=110"<<endl;
}
return 0;
}

for(int i = 0; i < 3; i++)
{
stack<int> oper_temp = oper;
stack<int> data_temp = data;
if(i == 0){
bestx[n] = 0;
if(!oper.empty()){
int op = oper.top();
if(op==1){//之前运算符是减
oper.pop();
oper.push(0);//将减号变成加号
int tp = data.top();
data.pop();
data.push(-tp);
}
}
oper.push(bestx[n]);
data.push(a[n]);
}else if(i == 1){
bestx[n] = 1;
if(!oper.empty()){
int op = oper.top();
if(op==1){//之前运算符是减
oper.pop();
oper.push(0);//将减号变成加号
int tp = data.top();
data.pop();
data.push(-tp);
}
}
oper.push(bestx[n]);
data.push(a[n]);
}else{
bestx[n] = 2;
int temp = data.top();
data.pop();
temp = temp*10+a[n];
data.push(temp);
}
calc(n+1);
oper = oper_temp;
data = data_temp;
}
}
int main()
{
data.push(1);//数据栈先进1
calc(1);
return 0;
}

运行

1□2□3□4□5□6□7□8□9=110_#include

总结

虽然代码思想在那,而且也知道怎么动手,但是还有出现了很多错误。比如刚开始的优先级,以及之后用栈运算后的将减法转换为加法的运算,都多多少少的出现了很多错误。

经验:纸上谈兵永远没有实践来得强。