题目说明
解题思路
前几天刚学完C++基础。所以首先要说明的是这是练手的时候弄的完全没有必要
的写法,虽然是也是对,但是绕了一个大圈,效率不高。
进正题,四则运算的话一般用栈比较容易实现,所以分别设置了数据栈和运算符栈。
一开始直接把每一行用例都当成一串完整的字符串输进去,然后逐位取出来判断,是运算符则保留string形式,是数字则转为int整形,对数字和运算符分别压栈处理。(这里绕远了
)
要注意的是,这种做法“-”负号会导致运算的时候出错,因为从栈顶读运算符,相当于从右往左运算,负号会被后面数字运算干扰,导致在和前面的数字相减出错,比如3x4-6+7,如果不对负号进行处理,那么运算便变成3x4-(6+7),所以应该每碰到一次负号,就对后一位数字进行取反,然后运算时不用相减而是相加就好了。
我采用的方法是×和÷两个运算符不进操作符栈,在栈外优先匹配运算处理,然后结果压入数据栈,只对+和-进行压栈延后处理运算。
代码
#include <iostream>
#include <string>
#include <sstream> //用来字符串转整形
#include <stack> //c++ STL自带的栈
using namespace std;
int whether24(string &str){
int sum;
stack <int> num; //数据栈
stack <string> cal; //运算符栈
stringstream ss;
string temp,tempcal; //几个中间变量
int tempnum1;
int length=str.length();
for(int i=0;i<length;i++){
temp=str[i];
if(temp!="x"&&temp!="/"&&temp!="+"){ //对数据压栈,但是负号额外处理
if(temp=="-"){ //碰到负号,对后一位数据取反压栈
temp=str[i+1];
tempnum1=stoi(temp,0,10); //转把string转int
num.push(-tempnum1);
cal.push(temp);
i=i+1;
continue;
}
else{
tempnum1=stoi(temp,0,10);
num.push(tempnum1);
}
}
else if(temp=="x"){ //对* /运算符直接开始数字运算,并进行压栈
temp=str[i+1];
tempnum1=stoi(temp,0,10)*num.top();
num.pop();
num.push(tempnum1);
i=i+1;
continue;
}
else if(temp=="/"){
temp=str[i+1];
tempnum1=num.top()/stoi(temp,0,10);
num.pop();
num.push(tempnum1);
i=i+1;
continue;
}
else{
cal.push(temp);
}
}
int callength=cal.size();
for(int j=0;j<callength;j++){ //因为已经对负号进行处理,在处理+ -数字运算的时候都用同一段代码直接加就行了
tempcal=cal.top();
cal.pop();
sum=num.top();
num.pop();
sum=sum+num.top();
num.pop();
num.push(sum);
}
return num.top(); //返回4则运算最终结果,即栈顶
}
int main(){
int n;
int judge;
cin>>n;
string str[n];
for(int i=0;i<n;i++){ //输入每一条字符串
cin>>str[i];
}
for(int i=0;i<n;i++){
judge=whether24(str[i]); //挨条处理,判断是否24
if(judge==24){
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
}
return 0;
}