逆波兰表达式
将中缀表达式(一个符号连接两个运算符) 转换为后缀表达式 ,( 这样可以保证每次操作数都是后缀表达式中符号前面的两个数 因此方便利用栈的结构 ) ,关键就是按照怎样的顺序转化为中缀表达式
1.首先输出的后缀表达式操作数顺序不变 ,即中缀表达式转化为后缀表达式的重点并不是操作数顺序 ,也不用为操作数建立栈
2.符号顺序会改变 ,且会将运算优先级高的符号更加靠近操作数 ,(可以按照优先级建栈 ,保证栈顶到栈底的优先级由高到低 ,出栈时即优先级高的先输出)
:比较top符号和当前符号优先级 ,若当前符号优先级低于top符号 ,则将top符号输出( 先输出保证了更加靠近操作数 ,即优先级高的更先运算 ),然后继续下一个top和当前符号 ,
ps :若当前符号优先级与top优先级相同,则也应该将top输出 ,这样保障了从左到右的运算顺序 ,对加法和乘法来说 ,可以互换顺序 ,而减法和除法必须保证从左到右的运算顺序 ,否则结果错误 ,
a+b-c 则 后缀表达式必须为 ab+c- ,这样就是先输出 + ,
只有遇到符号才开始运算 ,这也保证了运算顺序 ,
最后输出符号的个数是不变的(除了去掉了括号)
3.对括号的处理
若遇到左括号 ,直接将左括号进栈而不必输出任何符号 ,然后对左括号后进栈的元素采取 步骤2 而不必考虑左括号的影响 ,直到遇到右括号则按出栈顺序输出左右括号间的所有内容 ,
a + ( b - c * d - e) * c
a b c d * - e - c * +
#include<bits/stdc++.h>
using namespace std;
struct node {
char data;
node* next;
int level;
};
void pop(node* &top)
{
if (top == NULL) return;
node* p = top;
top = top->next;
free(p);
}
void push(node*& top, char c)
{
node* p = (node*)malloc(sizeof(node));
p->data = c;
p->next = top;
top = p;
}
//上面为栈的基本操作
void func1(char c ,node* &top)
{
node* p;
if (c >= 'a' && c <= 'z')
{
cout << c;
return;
}
else if (c == '(')
{
push(top, c);
return;
}
else if (c == ')')
{
while (top->data != '(')
{
cout << top->data;
pop(top);
}
pop(top);
return;
}
else
{
p = (node*)malloc(sizeof(node));
p->data = c;
if (c == '+' || c == '-')
p->level = 1;
else if (c == '*' || c == '/')
p->level = 2;
while (top!=NULL&&p->level <= top->level)
{
cout << top->data;
pop(top);
}
p->next = top;
top = p;
}
}
void func()
{
string s;
node* top = NULL;
getline(cin, s);
int len = s.length();
for (int i = 0; i < len; i++)
{
func1(s[i],top);
}
while (top != NULL)
{
cout << top->data;
top = top->next;
}
}
int main()
{
func();
}
ps : 除了在node中设置leve选项 ,也可以设置一个函数
int rank(char c)
{
if(c=='+'||c=='-') return 1 ;
else if(c=='*'||c=='/') return 0 ;
}
然后直接调用函数 rank(top->data) <= rank(c) ;
然后就是计算值 ,这次也只需要建立一个栈 ,将数字和符号放在同一个栈中 ,若top是符号 ,则取出top下面的两个元素 ,计算后返回结果返回top(可以将转换为中缀表达式的输出部分直接转成赋值)
PS :需要考虑的事情:当输入的是数字时 ,若多于一位数 ,接收为string需要转换成数字 ,
可以用字符数组接收每一位,然后转成确定的数字 (可能需要结合大数加减乘除运算)
string s ;
getline(cin,s) ;
int len=s.length() ;
vector<int> a ;
int j=0;
for(int i=0;i<len;i++)
{
while(s[i]>='0'&&s[i]<='9')
{
a[j]+=s[i]-'0' ;
a[j]*=10 ;
i++ ;
}
a[j]/=10 ;
j++ ;
}
int num = j ;
//更高效的方法 :将while循环的部分加入到判断类型的部分
含数字处理的后缀表达式
#include<bits/stdc++.h>
using namespace std;
struct node {
char data;
node* next;
int level;
};
void pop(node*& top)
{
if (top == NULL) return;
node* p = top;
top = top->next;
free(p);
}
void push(node*& top, char c)
{
node* p = (node*)malloc(sizeof(node));
p->data = c;
p->next = top;
top = p;
}
void func()
{
int a[100] = {0};
string s;
node* top = NULL;
getline(cin, s);
int len = s.length(),j=0;
for (int i = 0; i < len; i++)
{
node* p;
bool flag = 0;
if (s[i] >= '0' && s[i] <= '9') flag = 1;
while (s[i] >= '0' && s[i] <= '9')
{
a[j] += s[i] - '0';
a[j] *= 10;
i++;
}
if (flag == 1)
{
a[j] /= 10;
cout << a[j]<<;
j++;
}
int c = s[i];
if (c == '(')
{
push(top, c);
return;
}
else if (c == ')')
{
while (top->data != '(')
{
cout << top->data;
pop(top);
}
pop(top);
return;
}
else
{
p = (node*)malloc(sizeof(node));
p->data = c;
if (c == '+' || c == '-')
p->level = 1;
else if (c == '*' || c == '/')
p->level = 2;
while (top != NULL && p->level <= top->level)
{
cout << top->data;
pop(top);
}
p->next = top;
top = p;
}
}
while (top != NULL)
{
cout << top->data;
top = top->next;
}
}
int main()
{
func();
}