我建议每个像我一样的小白,都自己动手写一下,四则计算器,因为这里面既有队列的知识,又有栈的知识,又有字符串处理的知识,而且还可以对自己的逻辑思维进行一定强度的锻炼,可以说有百利而无一害!我这里写的代码仅供大家参考,因为比较简单我也没怎么写注释。talking is cheapshow me the code
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
const int INF=1000;
//调度场算法 中缀表达式转后缀表达式
template <typename T> queue<T>& dispatch(pair<T,int> infix[],long size){
//var can't use to convert type,but we can use it to define a type;
stack<pair<T, int>> operators;
queue<T>* result=new queue<T>;
for (int i=0; i<size; i++) {
if (infix[i].second==0) {//if it is a number;
result->push(infix[i].first);
}else if(infix[i].second!=INF){//or it is a operator;
if(operators.empty()){
operators.push(infix[i]);
}else if(infix[i].second>operators.top().second){
operators.push(infix[i]);
}else{
do{
result->push(operators.top().first);
operators.pop();
} while (!operators.empty()&&infix[i].second<=operators.top().second);
operators.push(infix[i]);
}
}
}
while(!operators.empty()){
result->push(operators.top().first);
operators.pop();
}
return *result;
}
//创建带有优先级的操作符pair
pair<string, int>* init_infix_pair(vector<string> infix,long size) {
pair<string, int>* opers=new pair<string,int>[size];
int current_priority=1;
for (int i=0; i<size; i++) {
pair<string,int> oper(infix[i],0);
if(infix[i]=="("){current_priority+=2;oper.second=INF;}
else if(infix[i]==")"){current_priority-=2;oper.second=INF;}
else if(infix[i]=="*"||infix[i]=="/"){
oper.second=current_priority+1;
}else if(infix[i]=="+"||infix[i]=="-"){
oper.second=current_priority;
}
opers[i]=oper;
}
return opers;
}
//把字符串转换成字符串数组,以运算符作为分隔符,可以处理小数点
vector<string>& convert_string_to_array(string exp){
int start,end;
vector<string>* vec=new vector<string>;
for (int i=0; i<exp.size(); i++) {
if(exp[i]>='0'&&exp[i]<='9'){
if(!isdigit(exp[i-1])&&exp[i-1]!='.'){
start=i;
}
}else{
if(exp[i]=='.')continue;
if(i==0||!isdigit(exp[i-1])){
vec->push_back(exp.substr(i,1));
}
else{
end=i;
vec->push_back(exp.substr(start,end-start));
vec->push_back(exp.substr(i,1));
}
}
}
return *vec;
}
//构建一个vector,元素为pair,first标识是数字还是运算符,second为具体内容
vector< pair<bool, double> >& convert_queue_to_vector(queue<string> result){
vector<pair<bool,double>>* vec=new vector<pair<bool,double>>;
while(!result.empty()){
char oper=*result.front().c_str();
if(oper=='+'||oper=='-'||oper=='*'||oper=='/'){
vec->push_back(pair<bool,double>(true,oper));
result.pop();
continue;
}
vec->push_back(pair<bool,double>(false,atof(result.front().c_str())));
result.pop();
}
return *vec;
}
//利用栈计算后缀表达式
double caculate_string_vector(vector<pair<bool, double>> vec){
stack<double> result_stack;
for (int i=0; i<vec.size(); i++) {
if(vec[i].first==false){
result_stack.push(vec[i].second);
}else{
double TF,TS;
double result;
TF=result_stack.top();
result_stack.pop();
TS=result_stack.top();
result_stack.pop();
if(vec[i].second=='+')
result=TS+TF;
if(vec[i].second=='-')
result=TS-TF;
if(vec[i].second=='*')
result=TS*TF;
if(vec[i].second=='/')
result=TS/TF;
result_stack.push(result);
}
}
return result_stack.top();
}
int main(){
string exp="(123.0+(45.75-20*(10-9)))*56.23+(3.2-100)";
vector<string>& vec=convert_string_to_array(exp);
vector<string>::iterator it=vec.begin();
while (it!=vec.end()) {
cout<<*it<<" ";
it++;
}
cout<<endl;
pair<string,int>* ps=init_infix_pair(vec,vec.size());
queue<string>& result=dispatch(ps,vec.size());
vector< pair<bool,double> >& final=convert_queue_to_vector(result);
cout<< caculate_string_vector(final)<<endl;
while(!result.empty()){
cout<<result.front()<<" ";
result.pop();
}
cout<<endl;
return 0;
}