中缀表达式和逆波兰式的相互转换

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/opooc/article/details/81188065

至于中缀表达式和逆波兰式是什么就不多阐述了。
中缀表达式和波兰式的相互转换思想是一样的

中缀表达式转逆波兰式

int judge(char data){
    int res = 0;
    switch (data) {
        case '+':
            res = 1;
            break;
        case '-':
            res = 1;
            break;
        case '*':
            res = 2;
            break;
        case '/':
            res = 2;
            break;
        default:
            break;
    }
    return res;
}
string getNiBolan(string str){
    string newStr = "";
    LinkStack stack;
    initStack(stack);
    int length =(int)str.length();
    for (int i =0 ; i<length; i++) {
        char cur = str[0];
        str= str.substr(1,length-1);
        if (cur == '(') {
            //新元素为(直接压栈
            push(stack, cur);
        }else if(cur ==')'){
            //新元素为)打印出(上面所有的
            if(!isEmpty(stack)){
                //栈中有元素
                //问题3忘记循环打印出
                while (!isEmpty(stack)) {
                    char peep = getTop(stack);
                    if (peep != '(') {
                        newStr += pop(stack);
                    }else {
                        pop(stack);
                        break;
                    }
                }
            }else{
                //没有元素遇到(直接报错
                PerException("the input is error");
            }
        }else if ( ('A'<=cur&&cur<='Z')||('a'<=cur && cur<='z')||('0'<=cur && cur<='9') ){
            //新元素为字符或者数字直接赋值
            newStr += cur;
        }else{
            //新元素为+-#/
            int curJudge1 = judge(cur);
            //当栈不为空的时候判断
            if (!isEmpty(stack)) {
                while (!isEmpty(stack)) {
                    char peep = getTop(stack);
                    //栈顶不为(
                    if (peep != '(') {
                        int curJudge2 = judge(getTop(stack));
                        //新元素大于等于栈顶的等级,直接压栈
                        if (curJudge1 >= curJudge2) {
                            push(stack, cur);
                            break;
                        }else{
                            //小于就弹出。赋值
                            newStr +=pop(stack);
                        }
                    }else{
                        //栈顶为(,直接压栈
                        push(stack, cur);
                        break;
                    }
                }
            }else{
                //问题2;忘记在空的时候直接压栈
                push(stack, cur);
            }
        }
    }
    //问题1 忘记了 打印出栈中的所有元素
    while (!isEmpty(stack)) {
        newStr += pop(stack);
    }
    return newStr;
}

逆波兰式转中缀表达式

string getZhongZhui(string str){
    string newStr ="";
    LinkStack stack;
    initStack(stack);
    int flag = 0;
    int length =(int)str.length();
    for (int i =0 ; i<length; i++) {
        char cur = str[0];
        str= str.substr(1,length-1);
        //是字符元素就压栈
        if ( ('A'<=cur&&cur<='Z')||('a'<=cur && cur<='z')||('0'<=cur && cur<='9') ) {
            push(stack, cur);
        }else if(cur == '+' || cur == '-'){
            //加减和乘除分开,加减要多加括号
            if (flag == 0) {
                //理解思路是处理完的再压栈,但是这里是要打印出字符串,所以采用 标志位。
                //如果标志位为0,就用栈中的对新字符串作用,如果标志位为1,
                //说明刚才算出的字符串被压栈后又有新的字符压入它的上面,所以要用才算出的字符串对新压入的字符进行处理.
                if (newStr.length() == 0) {
                    //开始时字符串为0,取两个栈中的元素.
                    char stackStrFirst = pop(stack);
                    char stackStrSecond = pop(stack);
                    newStr= newStr + "("+stackStrSecond + cur + stackStrFirst+")";
                    flag++;
                }else{
                    //new 的字符串有元素。取一个栈顶的元素。
                    char stackStr = pop(stack);
                    //这里使用了stringstream流。目的是让首字符char转成string.
                    stringstream stream;
                    stream<<stackStr;
                    string stackStrCopy = stream.str();
                    newStr = "("+stackStrCopy+cur+newStr+")";
                }
            }else{
                //标志位位1,弹出后直接被上一次作用的字符串操作。
                char stackStr = pop(stack);
                newStr = "("+newStr+cur+stackStr+")";
                flag--;
            }

        }else if(cur == '*' || cur =='/'){
            //处理逻辑和+- 的相同,只不过在处理的时候,不用加括号
            if (flag == 0) {
                if (newStr.length() == 0) {
                    char stackStrFirst = pop(stack);
                    char stackStrSecond = pop(stack);
                    newStr= newStr +stackStrSecond + cur + stackStrFirst;
                    flag++;
                }else{
                    char stackStr = pop(stack);
                    stringstream stream;
                    stream<<stackStr;
                    string stackStrCopy = stream.str();
                    newStr = ""+stackStrCopy+cur+newStr;
                }
            }else{
                char stackStr = pop(stack);
                newStr = newStr+cur+stackStr;
                flag--;
            }
        }

    }
    //如果字符串的首位有括号,直接去掉
    if (newStr[0]=='(' && newStr[newStr.length()-1] ==')' ) {
        newStr = newStr.substr(1,newStr.length()-2);
    }
    return newStr;
}

栈定义

//链式栈的定义(不带头结点,头插法)
//N->H->d->b->c->R
typedef struct LSNode{
    char data;
    LSNode* next;
}LSNode ,*LinkStack;

//初始化一个栈
void initStack(LinkStack &top){
    top =nullptr;
}
//清空一个栈
void clearStack(LinkStack &top){
    while (top != nullptr) {
        LSNode* p =top;
        top = top->next;
        delete p;
    }
}
//进栈
void push(LinkStack &top,char data){
    LSNode*p = new LSNode{data,top};
    top = p;
}
//出栈
char pop(LinkStack &top){
    if (top == nullptr) {
        PerException("the stack is empty");
    }
    int res = 0;
    LSNode* p = top;
    top = top->next;
    res = p->data;
    return res;
}
//查看栈顶元素
char getTop(LinkStack top){
    if (top == nullptr) {
        PerException("the stack is empty");
    }
    return top->data;
}
//求栈的长度
int length(LinkStack top){
    int count =0;
    LSNode* p =top;
    while (p!=nullptr) {
        p = p->next;
        count++;
    }
    return count;
}
//栈是否为空
bool isEmpty(LinkStack top){
    if (top == nullptr) {
        return true;
    }
    return false;
}
//栈是否为满
bool isFull(LinkStack top){
    return false;
}

测试数据

 int main(){
     cout<<getNiBolan("a+b*(c-d)/e")<<endl ;
     cout<<getZhongZhui("abcd-e/*+")<<endl;
 return 0;
 }
展开阅读全文

没有更多推荐了,返回首页