代码
具体讲解见代码注释
#include <bits/stdc++.h>
using namespace std;
set<char> operator_set;//运算符集合(括号也算在里面)
set<string> operator_str_set;//存的是字符串,方便inTOPost函数
vector<string> inOrder,postOrder;//中序表达式,以及后序表达式
map<string,int> prio;//各运算符优先级
/*
一些初始化工作
*/
void init(){
// operator_set.insert('+');
// operator_set.insert('-');
// operator_set.insert('*');
// operator_set.insert('/');
// operator_set.insert('%');
// operator_set.insert('(');
// operator_set.insert(')');
// operator_str_set.insert("+");
// operator_str_set.insert("-");
// operator_str_set.insert("*");
// operator_str_set.insert("/");
// operator_str_set.insert("%");
// operator_str_set.insert("(");
// operator_str_set.insert(")");
char s[10]={'+','-','*','/','%','(',')'};
string t="";
for(int i=0;i<7;i++){
operator_set.insert(s[i]);
t+=s[i];
operator_str_set.insert(t);
t="";
}
prio["("]=1;
prio["+"]=2;
prio["-"]=2;
prio["*"]=3;
prio["/"]=3;
prio["%"]=3;
}
/*
将字符串s按照运算符以及(),
分割为若干字符串,并返回到向量vs;
*/
void getStr(string s,vector<string> &vs){
int len = s.size();
string t="";
for(int i=0;i<len;i++){
if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'||s[i]=='%'||s[i]=='('||s[i]==')'){//需要改一下
if(t!="")
vs.push_back(t);
string temp(1,s[i]);
vs.push_back(temp);
t="";
}
else{
t+=s[i];
}
}
if(t!=""){
vs.push_back(t);
}
}
/*
将中序表达式,转为后序表达式
*/
void inToPostOrder(vector<string>& in,vector<string>& post){
stack<string> st;//辅助实现中序转后序;
string top="";
for(auto &in_ele : in){
if(in_ele=="+"||in_ele=="-"||in_ele=="*"||in_ele=="/"||in_ele=="%"){
if(st.empty()){
st.push(in_ele);
continue;
}
//此时st绝对不会为空,所以取栈顶可以不加判断
top=st.top();
// while(!st.empty()||prio[in_ele]<prio[top]){
// post.push_back(top);
// st.pop();
// top=st.top();
// }//弹出结束,压入当前元素in_ele
while(prio[in_ele]<=prio[top]){
post.push_back(top);
st.pop();
if(st.empty()){
break;
}
top=st.top();
}
st.push(in_ele);
}
else if(in_ele=="("){
st.push(in_ele);
}
else if(in_ele==")"){
while(1){
top = st.top();
st.pop();
if(top != "("){
post.push_back(top);
}
else{
break;
}
}
}
else{
post.push_back(in_ele);
}
}
while(!st.empty()){
post.push_back(st.top());
st.pop();
}
}
/*
根据后序表达式计算得到答案;
*/
int calAns(vector<string> &post){
stack<string> st;
string top1,top2,temps;
int temp=0;
for(auto &ele:post){
if(ele=="+"||ele=="-"||ele=="*"||ele=="/"||ele=="%"){
top2=st.top();
st.pop();
top1=st.top();
st.pop();
if(ele=="+"){
temp=(int)(stoi(top1))+(int)(stoi(top2));
}
else if(ele=="-"){
temp=(int)(stoi(top1))-(int)(stoi(top2));
}
else if(ele=="*"){
temp=(int)(stoi(top1))*(int)(stoi(top2));
}
else if(ele=="/"){
if(top2=="0"){
cout<<"除数为0,计算结束\n";
return -1;
}
temp=(int)(stoi(top1))/(int)(stoi(top2));
}
else if(ele=="%"){
if(top2=="0"){
cout<<"除数为0,计算结束\n";
return -1;
}
temp=(int)(stoi(top1))%(int)(stoi(top2));
}
temps = to_string(temp);
st.push(temps);
}
else{
st.push(ele);
}
}
return stoi(st.top());
}
bool judge(vector<string> in){
//检查括号是否匹配
int left=0;
for(auto& x:in){
if(x=="("){
left++;
}
else if(x==")"){
left--;
if(left<0){
cout<<"括号不匹配\n";
return 0;
}
}
}
if(left>0) return 0;
//检查运算符对不对
//为了简化,本计算器不支持输入负数
int len = in.size();
bool flag = (operator_str_set.find(in[len-1])!=operator_str_set.end())&&(in[len-1]!="(")&&(in[len-1]!=")")
||(operator_str_set.find(in[0])!=operator_str_set.end())&&(in[0]!="(")&&(in[0]!=")");
if(flag){//如果条件成立,则in[0] or in[len-1]是一个+-*/运算符
return 0;
}
//+-*%运算符不能在一起;
bool flag1,flag2,flag3;//flag123代表是不是+-*/%
for(int i=1;i<len-1;i++){
flag1 = (operator_str_set.find(in[i-1])!=operator_str_set.end())&&(in[i-1]!="(")&&(in[i-1]!=")");
flag2 = (operator_str_set.find(in[i])!=operator_str_set.end())&&(in[i]!="(")&&(in[i]!=")");
flag3 = (operator_str_set.find(in[i+1])!=operator_str_set.end())&&(in[i+1]!="(")&&(in[i+1]!=")");
if(flag2==1&&(flag==1||flag3==1)){
cout<<"存在两个运算符在一起的情况\n";
return 0;
}
}
//更多功能还待开发。(最近作业太多,做完了再来弄这个)
return 1;
}
void reset(){
inOrder.clear();
postOrder.clear();
}
void solve(){
init();
cout<<"输入一个中序表达式字符串:\n";
string s;
cin>>s;
getStr(s,inOrder);
if(!judge(inOrder)){
cout<<"检查到不合法表达式,请重新输入\n";
reset();
return ;
}
inToPostOrder(inOrder,postOrder);
cout<<calAns(postOrder)<<endl;
reset();
}
int main(){
while(1){
cout<<"*******************\n";
cout<<"* *\n";
cout<<"* 简易计算器实验 *\n";
cout<<"* 本人水平有限 *\n";
cout<<"* bug可能很多 *\n";
cout<<"* 欢迎大佬们的指正*\n";
cout<<"* *\n";
cout<<"*******************\n";
solve();
system("pause");
system("cls");
}
return 0;
}
//5*(4+(6+7))/2%8
一些运行样例
做的很粗糙,请多多指教