zoukankan      html  css  js  c++  java
  • 利用栈将中缀表达式转换为后缀表达式并进行计算

    [问题描述]
    中缀表达式是最普通的一种书写表达式的方式,而后缀表达式不需要用括号来表示,计算机可简化对后缀表达式的计算过程,而该过程又是栈的一个典型应用。
    [实验目的]
    (1) 深入理解栈的特性。
    (2) 掌握栈结构的构造方法。
    [实验内容及要求]
    (1) 中缀表达式中只包含+、-、×、/ 运算及( 和 )。
    (2) 可以输入任意中缀表达式,数据为一位整数。
    (3) 显示中缀表达式及转换后的后缀表达式(为清楚起见,要求每输出一个数据用逗
    号隔开)。
    (4) 对转换后的后缀表达式进行计算。
    [测试数据]
    (1) 6+3*(9-7)-8/2
    转换后的后缀表达式为:6397-*+82/-
    计算结果为:8
    (2) (8-2)/(3-1)*(9-6)
    转换后的后缀表达式为:82-31-/96-*
    计算结果为:9

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAXSIZE 512
    
    int top = -1;
    int stack[512];
    
    void Push(int e){
        if (top >= MAXSIZE){
            puts("栈已满");
            exit(1);
        }
        stack[++top] = e;
    
    }
    int isEmpty(){
        return top==-1?1:0;
    }
    int Pop(){
        if (top == -1){
            puts("这是一个空栈。");
            exit(1);
        }
        return stack[top--];
    }
    
    int getTop(){
        if (top < MAXSIZE)
            return stack[top];
        exit(1);
    }
    
    int judgePriority(char op1, char op2){
        // 1 先出栈, 再进栈
        // 0 直接进栈
        if (op1=='(' || op2 == '(')
            return 0;
        if ((op1=='-'||op1=='+')&& (op2 =='*'||op2 =='/'))
            return 0;
        return 1;
    }
    void infix2postfix(char *tmp, char *str){
        char *p = tmp;
        int i, j, k;
        char op1, op2;
        j = 0;
        for (i=0; p[i]; i++){
            // 数字
            if (p[i] >= '0' && p[i] <= '9')
                str[j++] = p[i];
            // 字符
            else{
                op1 = getTop();
                op2 = p[i];
                if (isEmpty())
                    Push(op2);
                // 非空
                else{
                    if (op2 == ')'){
                        while (getTop() != '(')
                            str[j++] = Pop();
                        Pop();
                        continue;
                    }
                    switch(judgePriority(op1, op2)){
                    case  1: str[j++] = Pop(); 
                        for (k=0; k<=top; k++){
                            if (!judgePriority(op1, op2)) break;
                            str[j++] = Pop();
                        }
                        Push(op2);
                        break;
                    case  0:  Push(op2); break;
                    }
                }
            }
        }
    
        while (!isEmpty())
            str[j++] = Pop();
        str[j] = 0;
    }
    
    int calc(char *buf){
        int i, k, j;
        for (i=0; buf[i]; i++){
            switch(buf[i]){
            case '+':
                k = Pop() + Pop();
                Push(k);
                break;
            case '-':
                j = Pop();
                k = Pop() - j;
                Push(k);
                break;
            case '*':
                k = Pop() * Pop();
                Push(k);
                break;
            case '/':
                j = Pop();
                k = Pop()/j;
                Push(k);
                break;
            default:
                Push(buf[i]-48);
            }
        }
        return Pop();
    
    }
    int main(){
        char tmp[512]="9-2*2+(9-8)", str[512];
        puts("输入运算表达式:");
        gets(tmp);
        infix2postfix(tmp,str);
        puts(str);
        printf("%s = %d
    ", tmp, calc(str));
    }

    这里写图片描述

  • 相关阅读:
    动态横向(水平)合并Repeater数据行DataItem的列
    动态绑数据(Repeater控件HeaderTemplate和ItemTemplate)
    动态横向(水平)合并GridView数据行DataRow的列
    动态绑数据(GridView控件Header和ItemTemplate)
    用具体列名替代星号
    如何实现数据行转换列显示
    用LINQ获取XML节点数据
    从字符串中获取XML节点数据
    字符串创建XML文档
    根据Attribute值条件对XML文档进行修改
  • 原文地址:https://www.cnblogs.com/laohaozi/p/12538391.html
Copyright © 2011-2022 走看看