描述:
1?2?3?4?5?6?7?8?9=110
在?处填上 +、-或者不填,构成的表达式判断是否正确,正确则输出(如果?处没有填写符号,则这几个数组成了一个新的N位数,比如1?2,可以是1+2,也可以是12)
思路:貌似目前我也想不到什么好方法,只能选最笨的方法了,暴力解吧。一共8个位置,且都在固定位置,每个位置有3种符号可以填,所以一共3的8次方种组合,搜索解决。每次在这8个位置上填上符号之后,都对组成的新字符串进行判断,看等式是否成立,若是成立,就进行输出。判断等式时,为了方便,我是先把字符串中的空格给去掉,组成一个新的字符串,对新的字符串进行类似于表达式求值的运算,判断是否成立。
这个题我竟然写了一个半小时!!!可怕 写的过程中出现了很多小问题。
- string 类型, 例如 string s=""; 那么此时就不能再对其进行s[1]='x';这样的赋值了。因为你定义了s是一个空串,即长度为0,那么再对比0大的下标位置赋值,就越界了。需要使用s+='x';这样对s[1]进行赋值。
- string s="123+456-7-8-9";运算数入栈,在求运算数时,是要每次乘以10,再加下一位的数字。另外,要注意字符类型与int型的转换,减去'0'。表达式求值时,刚开始我把每个算出来的运算数和运算符都放入栈,想着全部入栈后,再依次出栈两个运算数,出栈一个运算符,两数做完运算后再将结果入栈,重复,直至符号栈为空,此时运算符栈中剩下的一个数就是这个表达式的值。但我忽略了一个问题,我这样相当于是从后往前在算,运算数的顺序颠倒了,如果都是加法或者乘法还好,不会影响。但是对于剪发和除法来说,就有很大的问题。事实证明,连续出现两个减号,结果就会出错。后来我改成用数组来存储。,这样就可以从前往后遍历运算数和运算符,不会有表达式值计算错误的现象了。
没错,就是这两个小问题让我找了很长时间。所以在写程序时,一定得仔细了。
#include<bits/stdc++.h>
using namespace std;
string s="1 2 3 4 5 6 7 8 9=110";
string ss="";
char choose[3]= {'+','-',' '};
int q[10],qq,opp;
char op[10];
int sum=0;
void delete_kongge() {
ss="";
for(int i=0; i<17; i++) {
/*此处不能用ss[k++]=s[i],因为ss是一个空串,他的长度是0
对任意下标>0的位置赋值,都相当于越界
*/
if(s[i]!=' ') ss+=s[i];
}
}
int judge() {
delete_kongge();
int temp,num;
qq=0;opp=0;
for(int i=0; i<ss.length();) {
if(ss[i]>='0'&&ss[i]<='9') {
num=0;
while(ss[i]>='0'&&ss[i]<='9') {
num=num*10+(ss[i]-'0');
i++;
}
q[qq++]=num;
} else {
op[opp++]=ss[i];
i++;
}
}
int k=0;
for(int i=0;i<opp;i++){
int a=q[k++];
int b=q[k++];
char c=op[i];
if(c=='+') q[--k]=a+b;
else q[--k]=a-b;
}
if(q[k]==110) return 1;
else return 0;
}
void dfs(int x) {
if(x>15) {
if(judge()) cout<<s<<endl;
return;
}
for(int i=0; i<3; i++) {
s[x]=choose[i];
dfs(x+2);
}
}
int main() {
dfs(1);
return 0;
}