栈和队列的应用:
一、输出序列
给定出栈序列判断栈容量:
- 如果把图中出栈序列改为“入队后得到的出队序列”,则出栈序列不变(因为队列是先进先出);
- 如果把图中出栈序列改为“入栈后得到的出栈序列”,则出栈序列逆序(因为栈是先进后出)。
经典例题:已知出栈顺序求可能的入栈顺序。
要求的出栈顺序:
P1、……、Pi、……、Pj、……Pk、……、Pn
可能的入栈顺序:
其中只有第四组无法实现,因为如果最后一个入栈的元素第一个出栈,那么其余元素的出栈顺序就是固定的,不能乱来。
二、表达式转换
三种表达式:
1.中缀表达式: a+b
2.前缀表达式(波兰式): +ab
3.后缀表达式(逆波兰式): ab+
做法:变换符号位置,然后去括号
1.中缀表达式转换成前缀表达式:
2.中缀表达式转换成后缀表达式:
♥设计程序将中缀表达式转换为后缀表达式:
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
输出样例:
2 3 7 4 - * + 8 4 / +
c++代码实现:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 10;
typedef long long ll;
stack<char> sta;
int main() {
map<char,int> mp;
string str="2+3*(7-4)+8/4";//此例输出:2 3 7 4 - * + 8 4 / +
//cin>>str;
bool isfirst = true;
mp['-'] = 1,mp['+'] = 1;
mp['*'] = 2,mp['/'] = 2;
mp['('] = 3,mp[')'] = 3;
for(int i = 0; i<str.size(); i++) {
if(((i==0||str[i-1]=='(') && (str[i]=='+' || str[i] =='-')) || (str[i]>='0'&&str[i]<='9') || (str[i]=='.')) {
if(!isfirst) {
cout<<" ";
}
if(str[i]!='+') {
cout<<str[i];
}
while(str[i+1]=='.' || (str[i+1]>='0' && str[i+1]<='9')) {
i++;
cout<<str[i];
}
isfirst = false;
} else {
if(str[i]==')') {
while(!sta.empty() && sta.top()!='(') {
cout<<' '<<sta.top();
sta.pop();
}
sta.pop();
} else if(sta.empty()||mp[str[i]] > mp[sta.top()]) {
sta.push(str[i]);
} else {
while(!sta.empty() && sta.top()!='(') {
cout<<' '<<sta.top();
sta.pop();
}
sta.push(str[i]);
}
}
}
while(!sta.empty()) {
cout<<' '<<sta.top();
sta.pop();
}
return 0;
}
/*
1、建一个空栈储存运算符
2、当碰到数字直接输出,值的注意的是这里的数字可能是小数、负数(负号和数字是一起输出的)或带正号的数字;
3、当碰到运算符的时候,先比较当前符号a与栈顶符号b运算优先级的大小,如果a > b直接压入栈中,否则就输出栈中的运算符直到为空或栈顶元素为‘(’;
4、当碰到')'运算符的时候,直接输出栈中的运算符,直到栈为空或者碰到运算符'(';
5、最后输出栈中的运算符,直到栈为空。
6、最卡格式的一种情况就是运算符和右括号连续出现的情况比如2+(+5)-1,要仔细考虑输出格式的处理;
7、‘+’,‘-’和数字一起输出的情况是正负号的在字符串的第一位或者是正负号前边是‘(’,其余情况都是作为运算符处理的。
*/
3.后缀表达式转换成中缀表达式:
4.后缀表达式转换成前缀表达式: