Pergunta: Suponha que uma expressão consista em uma variável de uma letra, um operador binocular e parênteses (por exemplo: "(a*(b+c)-d)/e)". Tente escrever um algoritmo para converter uma expressão escrita corretamente em notação polonesa reversa.
Ideias de passos:
(1) Primeiro, duas pilhas precisam ser alocadas. A pilha s1 é usada para armazenar temporariamente os operadores (incluindo um símbolo de fim). Esse operador segue o princípio de que quanto maior a prioridade em direção ao topo da pilha, maior a prioridade na pilha; pilha s2 é usada para inserir o estilo polonês inverso, por conveniência, a pilha s1 precisa colocar um operador com a prioridade mais baixa primeiro, aqui é assumido como '#';
(2) Leia os caracteres x um por um da extremidade esquerda da fórmula infixa e execute as seguintes etapas sequencialmente:
1. Se x for um operando, analise o operando completo (aqui, por conveniência, letras são usadas em vez de números) e coloque x diretamente na pilha s2;
2. Se x for um operador, discuta de acordo com a situação:
- ①Se x for '(', coloque-o diretamente na pilha s1;
- ②Se x for ')', os operadores entre '(' mais próximos do topo da pilha s1 são retirados da pilha um a um, colocados na pilha s2 um a um, e '(' é descartado neste momento;
- ③Se x for um operador diferente de '(' e ')', discuta os seguintes casos:
- ③-1 Se o elemento superior da pilha atual s1 for '(', insira x diretamente na pilha s1;
- ③-2 Se o elemento superior da pilha atual s1 não for '(', compare x com o elemento superior da pilha s1, se a prioridade de x for maior que a prioridade do operador superior da pilha s1, empurre x diretamente para Pilha s1. Caso contrário, remova o operador superior da pilha s1 e empurre-o para a pilha s2 até que a prioridade do operador superior da pilha s1 seja menor que (excluindo igual a) a prioridade de x ou o topo da pilha s2 O operador é '(', em seguida, empurre x para a pilha s1;
- ③-1 Se o elemento superior da pilha atual s1 for '(', insira x diretamente na pilha s1;
(3) Após (2), verifique se a pilha s1 está vazia, caso contrário, coloque os elementos na pilha um a um e coloque-os na pilha s2 (excluindo '#');
(4) Depois que as etapas acima forem concluídas, a pilha s2 é o resultado da saída polonesa reversa. Mas a pilha s2 deve ser processada na ordem inversa, porque o primeiro caractere da expressão está na parte inferior da pilha neste momento;
Código:
#include <stack>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
bool compare_precedence(char a, char b);
string RPN(string expression);
int main()
{
cout <<"Please input the normal expression:" <<endl;
string expression;
cin >> expression;
string RPN_result = RPN(expression);
cout <<"The RPN of expression is: \n"<< RPN_result <<endl;
return 0;
}
string RPN(string expression){
stack<char> s1;//临时存储运算符
s1.push('#');
stack<char> s2;//输入逆波兰式
for (decltype(expression.size()) index = 0; index != expression.size(); index++){
char x = expression[index];
if((x>='a'&& x<='z') || (x>='A' && x<='Z')){
s2.push(x);
continue;
}
else if(x=='('){
s1.push(x);
continue;
}
else if(x==')'){
while(s1.top()!='('){
s2.push(s1.top());
s1.pop();
}
if(!s1.empty() && s1.top()=='(')
s1.pop();
continue;
}
else{
if(s1.top()=='('){
s1.push(x);
continue;
}
else{
while((!compare_precedence(x,s1.top())) && s1.top()!='('){
s2.push(s1.top());
s1.pop();
}
s1.push(x);
continue;
}
}
}
if(!s1.empty()){
while(s1.top()!='#'){
s2.push(s1.top());
s1.pop();
}
}
string result;
for (int index = 0; !s2.empty(); index++){
result = result + (string(1,s2.top()));
s2.pop();
}
reverse(result.begin(), result.end());
return result;
}
//比较a的优先级是否大于b,若是则返回true,否则返回false
bool compare_precedence(char a, char b){
if(b=='#')
return true;
else if(a=='*'||a=='/'||a=='%'){
if(b=='+'||b=='-')
return true;
else
return false;
}
else if(a=='+'||a=='-'){
return false;
}
else{printf("Operator compare error!"); return -1;}
}
teste:
Exemplo |
saída |
resultado |
((a+b)*cd)/h+v%e |
|
√ |
a+b/c*(d+f)-m |
|
√ |