用栈实现表达式求值

本文介绍了一种使用栈的数据结构来解析和计算数学表达式的方法。通过两个栈分别存储运算符和数字,并遵循一定的规则进行操作,可以高效地解决包含括号、加减乘除的复杂表达式求值问题。

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

用栈实现表达式求值:

import java.util.LinkedList;

public class Solution {

    public boolean isDigit(char c) {
        return c >= '0' && c <= '9';
    }

    public double compute(double a, char operator, double b) {
        switch (operator) {
            case '+':
                return a + b;
            case '-':
                return a - b;
            case '*':
                return a * b;
            case '/':
                if (b == 0) {
                    throw new RuntimeException("cannot divide 0");
                }
                return a / b;
            default:
                throw new UnsupportedOperationException();
        }
    }

    public int getPriority(char operator) {
        if (operator == '+' || operator == '-') {
            return 1;
        } else if (operator == '*' || operator == '/') {
            return 2;
        }
        return -1;
    }

    public void operate(LinkedList<Double> numStack, LinkedList<Character> operatorStack) {
        char operator = operatorStack.pop();
        double rightNum = numStack.pop();
        double leftNum = numStack.pop();
        double newNum = compute(leftNum, operator, rightNum);
        numStack.push(newNum);
    }

    public double solve(String s) {
        LinkedList<Double> numStack = new LinkedList<>();
        LinkedList<Character> operatorStack = new LinkedList<>();

        char[] chars = s.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            char currChar = chars[i];
            if (isDigit(currChar)) {
                int num = 0;
                while (i < chars.length && isDigit(chars[i])) {
                    num = num * 10 + (chars[i] - '0');
                    i++;
                }
                numStack.push((double) num);
                i--;
            } else if (currChar == '(') {
                operatorStack.push(currChar);
            } else if (currChar == ')') {
                while (operatorStack.peek() != '(') {
                    operate(numStack, operatorStack);
                }
                operatorStack.pop();
            } else {
                while (!operatorStack.isEmpty() && getPriority(currChar) <= getPriority(operatorStack.peek())) {
                    operate(numStack, operatorStack);
                }
                operatorStack.push(currChar);
            }
        }

        while (!operatorStack.isEmpty()) {
            operate(numStack, operatorStack);
        }

        return numStack.pop();
    }

    public static void main(String[] args) {
        System.out.println(new Solution().solve("1-10/2+(6*61-8+2*30)*5"));
    }
}

根据实时输入字符实现表达式求值

#include <iostream>
#include <cstdlib>
using namespace std;
#define maxsize 100
typedef struct SN
{
    double data[maxsize];
    int top;
} StackNode;
StackNode StackInit()
{
    StackNode s;
    s.top = -1;
    return s;
}

StackNode Pop(StackNode s)
{
    if(s.top == -1)
        cout << "栈为空!" << endl;
    else
        s.top--;
    return s;
}

StackNode Push(StackNode s, double x)
{
    if(s.top == (maxsize - 1))
        cout << "栈已满!" << endl;
    else
    {
        s.top++;
        s.data[s.top] = x;
    }
    return s;
}

double GetTop(StackNode s)
{
    if(s.top == -1)
        cout << "栈为空!" << endl;
    else
        return s.data[s.top];
}

char precede(char a, char b)
{
    char r;
    switch(b)
    {
    case '+' :
    case '-' :
        if (a == '(' || a == '#')
        {
            r = '<';
        }
        else
        {
            r = '>';
        }
        break;
    case '*' :
    case '/' :
        if (a == '*' || a == '/' || a == ')')
        {
            r = '>';
        }
        else
        {
            r = '<';
        }
        break;
    case '(' :
        if (a == ')')
        {
            cout << "括号匹配错误!" << endl;
            exit(-1);
        }
        else
        {
            r = '<';
        }
        break;
    case ')' :
        if (a == '(')
            r = '=';
        else if (a == '#')
        {
            cout << "没有左括号!" << endl;
            exit(-1);
        }
        else
            r = '>';
        break;
    case'#':
        if (a == '(')
        {
            cout << "没有右括号!" << endl;
            exit(-1);
        }
        else if (a == '#')
            r = '=';
        else
            r = '>';
        break;
    }
    return r;
}

double operate(double a, char theta, double b)
{
    double re;
    switch(theta)
    {
    case'+':
        re = a + b;
        break;
    case'-':
        re = a - b;
        break;
    case'*':
        re = a * b;
        break;
    case'/':
        if(b == '0')
            cout << "除数不能为零!" << endl;
        else
            re = a / b;
        break;
    }
    return re;
}

double Cal()
{
    StackNode optr, opnd;
    char ch;
    int i = 0;
    char num[100];
    int number1 = 0;
    char theta;
    double a, b;
    optr = StackInit();
    optr = Push(optr, '#');
    opnd = StackInit();
    cout << "请输入表达式并以#结束:" << endl;
    cin >> ch;
    while(!((ch == '#') && (GetTop(optr) == '#')))
    {
        if(ch >= '0' && ch <= '9')
        {
            while(ch >= '0' && ch <= '9')
            {
                num[i] = ch;
                i++;
                cin >> ch;
            }
            for(int k = 0; k < i; k++)
                number1 = number1 * 10 + (num[k] - '0');
            opnd = Push(opnd, number1);
            number1 = 0;
            i = 0;
        }
        else switch(precede(GetTop(optr), ch))
            {
            case'<':
                optr = Push(optr, ch);
                cin >> ch;
                break;
            case'=':
                optr = Pop(optr);
                cin >> ch;
                break;
            case'>':
                theta = GetTop(optr);
                optr = Pop(optr);
                a = GetTop(opnd);
                opnd = Pop(opnd);
                b = GetTop(opnd);
                opnd = Pop(opnd);
                opnd = Push(opnd, operate(b, theta, a));
                break;
            }
    }
    return (GetTop(opnd));
}

int main()
{
    cout << "表达式的值为:" << Cal() << endl;
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值