栈应用1:算术表达式求值

本文介绍了一种算法,用于将中缀表达式转换为后缀表达式,并详细展示了如何通过堆栈实现这一转换过程。此外,还提供了计算后缀表达式值得方法。通过具体例子说明了算法的有效性和正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要要理解后缀表达式是怎么由中缀表达式得来的
多写写算术表达式实际是怎么运算的(顺序)
后缀表达式是怎么运算的
使用(来提升运算符的优先级
运算符总是跟在第二个操作元的后面

package Evaluation;

import java.util.Scanner;

class Stack
{
    final int MaxSize = 10;
    char[] data = new char[MaxSize];
    int top;

    public Stack()
    {
        top = -1;
    }
}

// 运算符优先级
class Priority
{
    final int MaxOp = 7;
    final char[] ch = { '=', '(', '+', '-', '*', '/', ')' }; // 运算符
    final int[] lpri = { 0, 1, 3, 3, 5, 5, 6 }; // 左运算符优先级
    final int[] rpri = { 0, 6, 2, 2, 4, 4, 1 }; // 右运算符优先级
}

public class Main
{
    public static void main(String args[])
    {
        Scanner cin = new Scanner(System.in);
        String exp = cin.nextLine();
        exp = exp + "\0";
        char postexp[] = new char[30];
        trans(exp, postexp);
        System.out.println("中缀表达式:" + exp);
        int i = 0;
        char ch = postexp[i];
        while (ch != '\0')
        {
            System.out.print(ch);
            ch = postexp[++i];
        }
        System.out.println();
        System.out.println("表达式的值:" + compvalue(postexp));
    }

    // 判断是否为运算符
    public static boolean IsOp(char ch)
    {
        Priority pri = new Priority();
        for (int i = 0; i < pri.MaxOp; i++)
            if (ch == pri.ch[i])
                return true;
        return false;
    }

    // 求左运算符op的优先级
    public static int leftpri(char op)
    {
        Priority pri = new Priority();
        for (int i = 0; i < pri.MaxOp; i++)
            if (op == pri.ch[i])
                return pri.lpri[i];
        return 0;
    }

    // 求右运算符op的优先级
    public static int rightpri(char op)
    {
        Priority pri = new Priority();
        for (int i = 0; i < pri.MaxOp; i++)
            if (op == pri.ch[i])
                return pri.rpri[i];
        return 0;
    }

    // 返回op1与op2运算符优先级的比较结果
    public static int Precede(char op1, char op2)
    {
        if (leftpri(op1) == rightpri(op2))
            return 0;
        else if (leftpri(op1) < rightpri(op2))
            return -1;
        else
            return 1;
    }

    // 将算术表达式exp转换成后缀表达式postexp
    public static void trans(String exp, char[] postexp)
    {
        int i = 0;
        Stack Sop = new Stack();
        Sop.top++;
        Sop.data[Sop.top] = '='; // 将'='入栈
        int n = 0;
        char ch = exp.charAt(n);
        while (ch != '\0')
        {
            if (!IsOp(ch))
            {
                while (ch >= '0' && ch <= '9')
                {
                    postexp[i++] = ch;
                    ch = exp.charAt(++n);
                }
                postexp[i++] = '#';
            }
            else
            {
                switch (Precede(Sop.data[Sop.top], ch))
                {
                case -1: // 栈顶运算符优先级低
                    Sop.data[++Sop.top] = ch;
                    ch = exp.charAt(++n); // 继续扫描其他字符
                    break;
                case 0: // 只有括号满足这种情况
                    Sop.top--; // 退栈
                    ch = exp.charAt(++n); // 继续扫描其他字符
                    break;
                case 1:
                    postexp[i++] = Sop.data[Sop.top--]; // 退栈并输出到postexp中
                    break;
                }
            }
        }
        while (Sop.data[Sop.top] != '=')
        {
            postexp[i++] = Sop.data[Sop.top--];
        }
        postexp[i] = '\0';
    }

    // 计算后缀算数表达式
    public static float compvalue(char[] postexp)
    {
        Stack st = new Stack();
        float d, a, b, c;
        int i = 0;
        char ch = postexp[i];
        while (ch != '\0')
        {
            switch (ch)
            {
            case '+':
                a = st.data[st.top--];
                b = st.data[st.top--];
                c = b + a;
                st.data[++st.top] = (char) c;
                break;
            case '-':
                a = st.data[st.top--];
                b = st.data[st.top--];
                c = b - a;
                st.data[++st.top] = (char) c;
                break;
            case '*':
                a = st.data[st.top--];
                b = st.data[st.top--];
                c = b * a;
                st.data[++st.top] = (char) c;
                break;
            case '/':
                a = st.data[st.top--];
                b = st.data[st.top--];
                if (a != 0)
                {
                    c = b / a;
                    st.data[++st.top] = (char) c;
                } else
                {
                    System.out.println("除0错误");
                }
                break;
            default:
                d = 0;
                while (ch >= '0' && ch <= '9')
                {
                    d = 10 * d + (ch - '0');
                    ch = postexp[++i];
                }
                st.data[++st.top] = (char) d;
                break;
            }
            ch = postexp[++i];
        }
        return st.data[st.top];
    }
}

输入:
1+3*2-1
输出:
中缀表达式:1+3*2-1
1#3#2#*+1#-
表达式的值:6.0
输入:
(56-20)/(4+2)
输出:
中缀表达式:(56-20)/(4+2)
56#20#-4#2#+/
表达式的值:6.0

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值