[Estrutura de dados] C++ converte uma expressão bem escrita em polonês reverso

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;

 (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

Acho que você gosta

Origin blog.csdn.net/standingflower/article/details/127581291
Recomendado
Clasificación