使用中缀表达式实现一个简易计算机

开学学算法的第5天

使用中缀表达式基于栈实现一个简易的中缀表达式。

实现思路:先对其判断字符str.charAt(i)是数字还是运算符,如果是数字直接入数栈,如果是运算符先判断是否栈空,栈空则直接入栈,栈不为空则判断当前运算符优先级和栈顶运算符优先级比较,当前运算符优先小于等于栈顶运算符,出两个数字栈,一个字符栈并做运算,将运算结果入栈,并将当前运算符入栈。依次遍历完字符。最后判断字符栈是否为空,为空直接出数字栈为最终结果,不为空则出数字栈两个元素,出运算符栈一个元素并计算然后将结果入数字栈,直到运算符栈为空。

图解:
在这里插入图片描述

class stack<E>{
    private E[] arr;
    private int size;

    public stack(int capacity){
        arr = (E[]) new Object[capacity];
    }

    //入栈
    public void push(E val){
        if (isFull()){
            ensureCapacity();
        }
        arr[size] = val;
        size = size+1;
    }

    //出栈
    public E pop(){
        //判空
        if (isEmpty()){
            throw new RuntimeException("空栈");
        }
        //出栈一次就要进行元素的移动
        E val = arr[this.size-1];
        this.size--;

        this.arr = Arrays.copyOf(this.arr,size);
        return val;
    }

    //判空
    public boolean isEmpty(){
        return this.size == 0;
    }

    //判满
    public boolean isFull(){
        return this.size == this.arr.length;
    }

    //扩容
    public void ensureCapacity(){
        if (size == arr.length){
            this.arr = Arrays.copyOf(arr, arr.length *2 + 1);
        }
    }

    //获取栈顶元素
    public E peek(){
        return this.arr[size-1];
    }
}

public class ComputerDemo {
    public static void main(String[] args) {
        stack<Integer> number = new stack<>(10);
        stack<Character> chars = new stack<>(10);
        String expression = "7*2*2-5+1-5+3-4";
        calculator(number,chars,expression);
    }
    //中缀
    public static void calculator(stack<Integer> number,stack<Character> chars,String expression){
        for (int i = 0; i < expression.length(); i++) {
            if (Character.isDigit(expression.charAt(i))){
                //表示当前字符为数字
                String s = String.valueOf(expression.charAt(i));
                int j = i+1;
                String tmp = new String();
                //这里出现70+2这种情况将数字拼接起来
                while (j < expression.length()){
                    if (Character.isDigit(expression.charAt(j))){
                        tmp+=expression.charAt(j);
                    }else {
                        break;
                    }
                    j++;
                }
                i = j -1;
                s += tmp;
                Integer value = new Integer(s);
                //将连续两个数字的字符拼接起来并入栈
                number.push(value);
            }else{
                //运算符
                if (chars.isEmpty()){
                    //字符栈为空直接入栈
                    chars.push(expression.charAt(i));
                }else{
                    int priority = priority(expression.charAt(i));
                    Character peek = chars.peek();
                    int peeks = priority(peek);
                    //将当前字符与栈中的字符作比较
                    if (priority <= peeks){
                        int num1 = number.pop();
                        int num2 = number.pop();
                        Character pop = chars.pop();
                        int compute = compute(num1, num2, pop);
                        //将计算结果入栈
                        number.push(compute);
                        //将当前运算符入栈
                        chars.push(expression.charAt(i));
                    }else {
                        chars.push(expression.charAt(i));
                    }
                }
            }
        }
        //需要对其符号栈做出判空处理  如果为空则直接打印number栈即可,否则继续计算
        while (!chars.isEmpty()){
            Character pop = chars.pop();
            Integer num1 = number.pop();
            Integer num2 = number.pop();
            int res = compute(num1, num2, pop);
            number.push(res);
        }

        System.out.println(number.pop());
    }

    //设置运算符的优先级,优先级越高数字值越大
    public static int priority(char oper){
        if (oper == '*' || oper == '/'){
            return 1;
        }else if (oper == '+' || oper == '-'){
            return 0;
        }else{
            return -1;
        }
    }


    //计算方法
    public static int compute(int num1,int num2,char oper){
        int res = 0;
        switch (oper){
            case '+':
                res = num1+num2;
                break;
            case '/':
                res = num2/num1;
                break;
            case '*':
                res = num1*num2;
                break;
            case '-':
                res = num2 - num1;
                break;
        }
        return res;
    }


}

在这里插入图片描述
点个赞呗~

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
表达式计算说明 很久就想编一个这样的计算器,只可惜一直没什么思路,最近突然灵感来了,所以就写下 这个程序。现在还在测试阶段,所以功能不是很完善。 程序功能:基本的表达式运算,可以自定义函数跟常量,分别保存在 “常数.txt” 和 “函数.txt”,方便自己添加。双击相应的函数名或常数名就可以将函数或常量添加到表达式中。 计算过程只能当表达式只有一行时有效。 实例1:计算sqr(19+tan(98)*tan(91)-sin(122)*(5*5-(19-11)))/2 计算过程sqr(19+tan(98)*tan(91)-sin(122)*(5*5-(19-11)))/2 =sqr(19+-7.11536972238419*tan(91)-sin(122)*(5*5-(19-11)))/2 =sqr(19+-7.11536972238419*-57.2899616307588-sin(122)*(5*5-(19-11)))/2 =sqr(19+-7.11536972238419*-57.2899616307588-.848048096156426*(5*5-(19-11)))/2 =sqr(19+-7.11536972238419*-57.2899616307588-.848048096156426*(5*5-8))/2 =sqr(19+-7.11536972238419*-57.2899616307588-.848048096156426*17)/2 =20.3032618253667/2 =10.1516309126834 实例2:计算 a=34 b=55 c=a+1 圆的面积(c) a*b c=a+b 圆的面积(c) 以下是计算结果: 圆的面积(c)=3848.4510006475 a*b=1870 圆的面积(c)=24884.5554090847 内置函数: !(x) - x 的阶乘 lg(x),log(x) 以10为底的对数 ln(x) 以 e为底x的对数 pow(x,y) x的y方次幂 prime(x) 判定x是否是素数,如果是直接将s2返回,否则将其各因子用连乘返回 sqr(x),sqrt(x) - x 的二次方根 arcsin(x) - x 的反正弦 arccos(x) - x 的反余弦 arcsec(x) - x 的反正割 arccsc(x) - x 的反余割 atn(x),arctg(x) - x 的反正切 arcctg(x) - x 的反余切 sin(x) - x 的正弦 cos(x) - x 的余弦 sec(x) - x 的正割 csc(x) - x 的余割 tg(x),tan(x) - x 的正切 ctg(x) - x 的余切 harcsin(x) - x 的反双曲正弦 harccos(x) - x 的反双曲余弦 harcsec(x) - x 的反双曲正割 harccsc(x) - x 的反双曲余割 harctg(x),harctan(x) - x 的反双曲正切 harcctg(x) - x 的反双曲余切 hsin(x) - x 的双曲正弦 hcos(x) - x 的双曲余弦 hsec(x) - x 的双曲正割 hcsc(x) - x 的双曲余割 htg(x),htan(x) - x 的双曲正切 hctg(x) - x 的双曲余切 有什么意见或建议可以跟我联系Email: ldm.menglv@gmail.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值