东软学习小组成员:夜枫
先看效果图:
没有写判断表达式正确与否的函数,所以只能识别正确的表达式,可以有小数括号如:6.2+2*(3-2)-3/2
结果为:6.7,已经在程序上测试


普通式子为中缀表达式:如 6+2-3/3=?
而如果用电脑计算则无法判断优先级,故此转换为后缀表达式:6 2 + 3 3 / -来解决优先级问题
转换思路为:用栈来处理优先级
栈的特点为:先进后出,只有一个出口。
队列特点为:先进先出,由两个出口。
拿到一个中缀表达式,首先需要将其转换为后缀表达式。
c++代码
需要的头文件:
#include<iostream>
#include<stack>//栈
#include<queue>//队列
#include<map>//map是一种关联容器
#include<math.h>
#include<string>
将中缀表达式的字符串改为后缀的方法:
queue<node> Change_infix_to_suffix(string str);// 将中缀表达式的str修改为后缀表示式子,并返回一个队列,队列元素类型为结构体{}
/*typedef struct Node{
bool falg;//判断node元素是算术符号还是数字,true为算术运算符
double num;//
char tp;
}node;
*/
queue<node> Change_infix_to_suffix(string str){
queue<node> q;
int len=str.length();//字符窜的长度
//遍历每一个字符,并做出判断,如果为左括号,压栈,如果为右括号,一直弹栈直到左括号,如果为数字,进队列,如果为算术符号,
//弹出所有比该字符优先级大的字符,直到比其小为止
node temp;
for(int i=0;i<len;){
if(str[i]=='('){
temp.falg=true;
temp.tp=str[i];
s.push(temp);
i++;
}
else if(str[i]==')'){
while(!s.empty()&&s.top().tp!='('){
q.push(s.top());
s.pop();
}
s.pop();//弹出左括号,但不进队列
i++;
}
else if(isdigit(str[i])){
//数字,不一定为是个位数,也不一定为整数
double num;
num=str[i]-'0';
i++;
while(i<len&&str[i]>='0'&&str[i]<='9'){//处理整数
num=num*10+str[i]-'0';
i++;
}
//处理小数;
int l=0;//小数后几位
if(str[i]=='.'&&i<len){
i++;
while(isdigit(str[i])){
num =num+(str[i]-'0')*(pow(0.1,++l));
i++;
}
}
temp.falg=false;
temp.num=num;
//因为是数字,进入队列
q.push(temp);
}
else{
while(!s.empty() && ( p[s.top().tp]>=p[str[i]] ) ){
q.push(s.top());
s.pop();
}
temp.falg=true;
temp.tp=str[i];
s.push(temp);
i++;
}
printfqueueAndstack(q,s);
}
//所有已经遍历完将栈中的所有元素弹出
while(!s.empty()){
q.push(s.top());
s.pop();
}
printfqueueAndstack(q,s);
return q;
}
打印队列和栈种的元素的方法:
void printfqueueAndstack(queue<node> q,stack<node> s){
stack<node> t1=s;
queue<node> t=q;
stack<node> t1s;
node cud;
cout<<"\n栈中的元素为:";
while(!t1.empty()){
cud=t1.top();
t1s.push(cud);
t1.pop();
}
while(!t1s.empty()){
cud=t1s.top();
cout<<cud.tp<<" ";
t1s.pop();
}
cout<<"\n队列中的元素为:";
while(!t.empty()){
cud=t.front();
if(cud.falg==true) cout<<cud.tp<<" ";
else cout<<cud.num<<" ";
t.pop();
}
cout<<"\n\n";
}
double Evaluate_suffix_expression(queue q)方法;//计算后缀表达式,并将结果返回为字符串类型
double Evaluate_suffix_expression(queue<node> q){
double reuse;
queue<node> tq=q;//拿到队列
//遍历队列
node cur;
stack<node> ts;
double a,b;
while(!tq.empty()){
cur=tq.front();
if(cur.falg==false){
//如果是数字,则放进栈中
ts.push(cur);
tq.pop();
}
else{
//如果是算术符号则从栈中取出两个,进行计算,将结果在放进去
b=ts.top().num;
ts.pop();
a=ts.top().num;
ts.pop();
char c=cur.tp;
double res;
switch(c){
case '*':
res=a*b;
break;
case '/':
res=a/b;
break;
case '+':
res=a+b;
break;
case '-':
res=a-b;
break;
}
cur.falg=false;
cur.num=res;
ts.push(cur);
tq.pop();
}
}
reuse=ts.top().num;
ts.pop();
return reuse;
}
c++源代码:
#include<iostream>
#include<stack>
#include<queue>
#include<map>
#include<math.h>
#include<string>
using namespace std;
map<char,int> p;
typedef struct Node{
bool falg;//true为算术运算符
double num;
char tp;
}node;
//typedef struct Node node;
stack<node> s;
queue<node> q;
stack<node> s1;
void printfqueueAndstack(queue<node> q,stack<node> s);//打印队列和栈中的元素
queue<node> Change_infix_to_suffix(string str);// 将中缀表达式的str修改为后缀表示式子,并返回一个队列,队列元素类型为结构体{}
/*typedef struct Node{
bool falg;//true为算术运算符
double num;
char tp;
}node;
*/
double Evaluate_suffix_expression(queue<node> q);//计算后缀表达式,并将结果返回为字符串类型
int main(void){
p['*']=p['/']=1;
p['-']=p['+']=0;
p['(']=p[')']=-1;
string str;
cin>>str;
q=Change_infix_to_suffix(str);
queue<node> tem=q;
node cue;
// cout<<"\n结果为:";
// while(!q.empty()){
// cue=q.front();
// if(cue.falg==true) cout<<cue.tp<<" ";
// else cout<<cue.num<<" ";
// q.pop();
// }
double res=Evaluate_suffix_expression(q);
cout<<"计算结果为: "<<res<<endl;
}
void printfqueueAndstack(queue<node> q,stack<node> s){
stack<node> t1=s;
queue<node> t=q;
stack<node> t1s;
node cud;
cout<<"\n栈中的元素为:";
while(!t1.empty()){
cud=t1.top();
t1s.push(cud);
t1.pop();
}
while(!t1s.empty()){
cud=t1s.top();
cout<<cud.tp<<" ";
t1s.pop();
}
cout<<"\n队列中的元素为:";
while(!t.empty()){
cud=t.front();
if(cud.falg==true) cout<<cud.tp<<" ";
else cout<<cud.num<<" ";
t.pop();
}
cout<<"\n\n";
}
queue<node> Change_infix_to_suffix(string str){
queue<node> q;
int len=str.length();//字符窜的长度
//遍历每一个字符,并做出判断,如果为左括号,压栈,如果为右括号,一直弹栈直到左括号,如果为数字,进队列,如果为算术符号,
//弹出所有比该字符优先级大的字符,直到比其小为止
node temp;
for(int i=0;i<len;){
if(str[i]=='('){
temp.falg=true;
temp.tp=str[i];
s.push(temp);
i++;
}
else if(str[i]==')'){
while(!s.empty()&&s.top().tp!='('){
q.push(s.top());
s.pop();
}
s.pop();//弹出左括号,但不进队列
i++;
}
else if(isdigit(str[i])){
//数字,不一定为是个位数,也不一定为整数
double num;
num=str[i]-'0';
i++;
while(i<len&&str[i]>='0'&&str[i]<='9'){//处理整数
num=num*10+str[i]-'0';
i++;
}
//处理小数;
int l=0;//小数后几位
if(str[i]=='.'&&i<len){
i++;
while(isdigit(str[i])){
num =num+(str[i]-'0')*(pow(0.1,++l));
i++;
}
}
temp.falg=false;
temp.num=num;
//因为是数字,进入队列
q.push(temp);
}
else{
while(!s.empty() && ( p[s.top().tp]>=p[str[i]] ) ){
q.push(s.top());
s.pop();
}
temp.falg=true;
temp.tp=str[i];
s.push(temp);
i++;
}
printfqueueAndstack(q,s);
}
//所有已经遍历完将栈中的所有元素弹出
while(!s.empty()){
q.push(s.top());
s.pop();
}
printfqueueAndstack(q,s);
return q;
}
double Evaluate_suffix_expression(queue<node> q){
double reuse;
queue<node> tq=q;//拿到队列
//遍历队列
node cur;
stack<node> ts;
double a,b;
while(!tq.empty()){
cur=tq.front();
if(cur.falg==false){
//如果是数字,则放进栈中
ts.push(cur);
tq.pop();
}
else{
//如果是算术符号则从栈中取出两个,进行计算,将结果在放进去
b=ts.top().num;
ts.pop();
a=ts.top().num;
ts.pop();
char c=cur.tp;
double res;
switch(c){
case '*':
res=a*b;
break;
case '/':
res=a/b;
break;
case '+':
res=a+b;
break;
case '-':
res=a-b;
break;
}
cur.falg=false;
cur.num=res;
ts.push(cur);
tq.pop();
}
}
reuse=ts.top().num;
ts.pop();
return reuse;
}
来源:CSDN
作者:夜枫之家
链接:https://blog.csdn.net/qq_43727225/article/details/104087477