前言
本文目的是记录学习过程,理论部分来自其他博主的转载,代码是自己实现,使用了STL的头文件。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include <vector>
using namespace std;
一、中缀表达式转后缀表达式
初始化一个栈,用于保存暂时还不能确定运算顺序的运算符。从左到右处理各个元素,直到末尾。可能遇到三种情况:
遇到操作数: 直接加入后缀表达式。
遇到界限符: 遇到 ‘(’ 直接入栈; 遇到 ‘)’ 则依次弹出栈内运算符并加入后缀表达式,直到弹出 ‘(’ 为止。注意: '(' 不加入后缀表达式。
遇到运算符: 依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,若碰到 ‘(’ 或栈空则停止。之后再把当前运算符入栈。
按上述方法处理完所有字符后,将栈中剩余运算符依次弹出,并加入后缀表达式。
————————————————
版权声明:本文为CSDN博主「胖胖的懒羊羊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44867340/article/details/119455799
stack<int>jishuan;
vector<char>bolan;
string s="1+(9-1)*2/1+5";
stack<char>yunshuanfu;
for(int i=0; i<s.size(); i++)
{
switch(s[i])
{
case '(':
yunshuanfu.push(s[i]);
break;
case ')':
while(1)
{
if(yunshuanfu.top()=='(')
{
yunshuanfu.pop();
break;
}
else
{
bolan.push_back(yunshuanfu.top());
yunshuanfu.pop();
}
}
break;
case '+': bolan.push_back('#');
while(!yunshuanfu.empty())
{
if(yunshuanfu.top()=='(')
break;
else
{
bolan.push_back(yunshuanfu.top());
yunshuanfu.pop();
}
}
yunshuanfu.push(s[i]);
break;
case'-': bolan.push_back('#');
while(!yunshuanfu.empty())
{
if(yunshuanfu.top()=='(')
break;
else
{
bolan.push_back(yunshuanfu.top());
yunshuanfu.pop();
}
}
yunshuanfu.push(s[i]);
break;
case'*': bolan.push_back('#');
while(!yunshuanfu.empty())
{
if(yunshuanfu.top()=='('||yunshuanfu.top()=='+'||yunshuanfu.top()=='-')
break;
else
{
bolan.push_back(yunshuanfu.top());
yunshuanfu.pop();
}
}
yunshuanfu.push(s[i]);
break;
case'/': bolan.push_back('#');
while(!yunshuanfu.empty())
{
if(yunshuanfu.top()=='('||yunshuanfu.top()=='+'||yunshuanfu.top()=='-')
break;
else
{
bolan.push_back(yunshuanfu.top());
yunshuanfu.pop();
}
}
yunshuanfu.push(s[i]);
break;
default:
bolan.push_back(s[i]);
}
}
while(!yunshuanfu.empty())
{
bolan.push_back(yunshuanfu.top());
yunshuanfu.pop();
}
二、后缀表达式计算
用栈实现后缀表达式的计算(栈用来存放当前暂时不能确定运算次序的操作数)
步骤1: 从左往后扫描下一个元素,直到处理完所有元素;
步骤2: 若扫描到操作数,则压入栈,并回到步骤1;否则执行步骤3;
步骤3: 若扫描到运算符,则弹出两个栈顶元素,执行相应的运算,运算结果压回栈顶,回到步骤1;
注意: 先出栈的是“右操作数”
————————————————
版权声明:本文为CSDN博主「胖胖的懒羊羊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44867340/article/details/119455799
代码如下(示例):
//--------下面是后缀表达式的求解过程-------
int z,y;//z代表计算左值,y代表计算右值
for(int j=0; j<bolan.size(); j++)
{
if(bolan[j]>='0'&&bolan[j]<='9')
{
int x=(bolan[j]-'0');
while(bolan[j+1]>='0'&&bolan[j+1]<='9')
{ j++;
x=x*10+(bolan[j]-'0');
}
jishuan.push(x);
}
else{
switch(bolan[j])
{
case '+':
y=jishuan.top();
jishuan.pop();
z=jishuan.top();
jishuan.pop();
jishuan.push(z+y);
break;
case '-':
y=jishuan.top();
jishuan.pop();
z=jishuan.top();
jishuan.pop();
jishuan.push(z-y);
break;
case'*':
y=jishuan.top();
jishuan.pop();
z=jishuan.top();
jishuan.pop();
jishuan.push(z*y);
break;
case'/':
y=jishuan.top();
jishuan.pop();
z=jishuan.top();
jishuan.pop();
jishuan.push(z/y);
break;
}
}
}
三、总体代码
代码如下(示例):
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include <vector>
using namespace std;
int main()
{
stack<int>jishuan;
vector<char>bolan;
string s="1+(9-1)*2/1+5";
stack<char>yunshuanfu;
for(int i=0; i<s.size(); i++)
{
switch(s[i])
{
case '(':
yunshuanfu.push(s[i]);
break;
case ')':
while(1)
{
if(yunshuanfu.top()=='(')
{
yunshuanfu.pop();
break;
}
else
{
bolan.push_back(yunshuanfu.top());
yunshuanfu.pop();
}
}
break;
case '+': bolan.push_back('#');//在两个相邻数字之间创造空格,起区分作用
while(!yunshuanfu.empty())
{
if(yunshuanfu.top()=='(')
break;
else
{
bolan.push_back(yunshuanfu.top());
yunshuanfu.pop();
}
}
yunshuanfu.push(s[i]);
break;
case'-': bolan.push_back('#');
while(!yunshuanfu.empty())
{
if(yunshuanfu.top()=='(')
break;
else
{
bolan.push_back(yunshuanfu.top());
yunshuanfu.pop();
}
}
yunshuanfu.push(s[i]);
break;
case'*': bolan.push_back('#');
while(!yunshuanfu.empty())
{
if(yunshuanfu.top()=='('||yunshuanfu.top()=='+'||yunshuanfu.top()=='-')
break;
else
{
bolan.push_back(yunshuanfu.top());
yunshuanfu.pop();
}
}
yunshuanfu.push(s[i]);
break;
case'/': bolan.push_back('#');
while(!yunshuanfu.empty())
{
if(yunshuanfu.top()=='('||yunshuanfu.top()=='+'||yunshuanfu.top()=='-')
break;
else
{
bolan.push_back(yunshuanfu.top());
yunshuanfu.pop();
}
}
yunshuanfu.push(s[i]);
break;
default:
bolan.push_back(s[i]);
}
}
while(!yunshuanfu.empty())
{
bolan.push_back(yunshuanfu.top());
yunshuanfu.pop();
}
//--------下面是后缀表达式的求解过程-------
int z,y;//z代表计算左值,y代表计算右值
for(int j=0; j<bolan.size(); j++)
{
if(bolan[j]>='0'&&bolan[j]<='9')
{
int x=(bolan[j]-'0');//-'0'是字符数字转整型数字的方法
while(bolan[j+1]>='0'&&bolan[j+1]<='9')
{ j++;
x=x*10+(bolan[j]-'0');
}
jishuan.push(x);
}
else{
switch(bolan[j])
{
case '+':
y=jishuan.top();
jishuan.pop();
z=jishuan.top();
jishuan.pop();
jishuan.push(z+y);
break;
case '-':
y=jishuan.top();
jishuan.pop();
z=jishuan.top();
jishuan.pop();
jishuan.push(z-y);
break;
case'*':
y=jishuan.top();
jishuan.pop();
z=jishuan.top();
jishuan.pop();
jishuan.push(z*y);
break;
case'/':
y=jishuan.top();
jishuan.pop();
z=jishuan.top();
jishuan.pop();
jishuan.push(z/y);
break;
}
}
}
cout<<"计算结果是"<<":"<<jishuan.top()<<endl;
}
总结
主要考察栈的基本操作和字符的读取转换,如有问题请指正。
1493

被折叠的 条评论
为什么被折叠?



