数据结构应用:计算器的实现

 最近开始学习数据结构,已了解:顺式线性表-链式线性表-栈-队列。做个小应用,巩固下知识。

该计算器 能运算所有四则运算,不包括括号。

概念解释:

我们平时说的四则运算表达式又叫逆波兰表达式,或者中缀表达式,及运算符中两个数之间

后缀表达式:运算符在两个数之后,且从左向右运算,没有运算符优先级

       例如:1 2 + ,1为被加数,2为加数变成四则运算为 1+2 =3。 

       再例如:1 2 + 4 *   :先运算第一个符号“+”变成 3 4 * ,在运算“*”,结果是12。

ok,计算器编写的核心就在于将中缀表达式变成 能遍历的后缀表达式。

而难点又在与优先级的转换,我这里定义的转换规则是:

数字输出,运算符进栈,栈顶符号优先级高输出,低/等于压栈

代码如下:

package com.study.stack;

import java.util.Stack;

/**
 * @author lvbowei
 * @date 2019/8/29
 */
public class Jisuanqi {
    static Stack<Object> shu = new Stack<>();
    static Stack<Character> fu = new Stack<>();

    public static void main(String[] args) {

        String s = "1+2*3-10/2";

        Stack stack = toHouZhui(s);
        System.out.println("后缀表达式:"+stack.toString());
        //倒叙
        Stack endStack = new Stack();
        int size = stack.size();
        for (int i = 0; i < size; i++) {
            endStack.push(stack.pop());
        }
        //这里用链表进行计算,只为了熟悉链表,你们可以使用栈也是很不错的。
        Node<Object> prevNode = null;
        int size1 = endStack.size();
        for (int i = 0; i < size1; i++) {
            Object c = endStack.pop();
            if (c.equals('+')||c.equals('-')||c.equals('*')||c.equals('/')){
                //
                String sss = prevNode.prev.item.toString()+c+prevNode.item.toString();
                System.out.println("计算过程:"+sss);
                Double left = Double.valueOf(prevNode.prev.item.toString());
                Double right = Double.valueOf(prevNode.item.toString());
                Double result ;
                if (c.equals('+')){
                    result = left + right;
                }else if (c.equals('-')){
                    result = left - right;
                }else if (c.equals('*')){
                    result = left * right;
                }else{
                    result = left / right;
                }
                Node<Object> objectNode = new Node<>(prevNode.prev.prev, result);
                prevNode.prev = null;//赋null ,gc
                prevNode = objectNode;
            }else{
                Node<Object> objectNode = new Node<>(prevNode, c);
                prevNode = objectNode;
            }
        }
        System.out.println("计算结果:"+prevNode.item);

    }

    private static class Node<E>{
        E item;
        Node<E> prev;
        Node(Node<E> prev,E item){
            this.prev = prev;
            this.item = item;
        }
    }

    private static Stack toHouZhui(String s) {
        char[] chars = s.toCharArray();
        String temp = "";
        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];
            if (c=='+'||c=='-'||c=='*'||c=='/'){
                if (!temp.equals("")){
                    temp = pushShu(shu, temp);
                }
                pushFu(fu, c);
            }else{
                temp+=c;
                if (i==(chars.length-1)){
                    temp = pushShu(shu, temp);
                }
            }
        }
        int size = fu.size();
        for (int i = 0; i < size; i++) {
            Character top = fu.pop();
            shu.push(top);
        }
        return shu;
    }

    private static void pushFu(Stack<Character> fu, char c) {
        int size = fu.size();
        for (int i = 0; i < size; i++) {
            Character top = fu.peek();
            if (compare(top,c)){//栈顶优先级高输出
                shu.push(fu.pop());
            }else {
                break;
            }
        }

        fu.push(c);

    }

    private static String pushShu(Stack<Object> shu, String temp) {
        shu.push(Double.valueOf(temp));

        return "";
    }

    /**
     * 比较运算符的优先级
     * @param a
     * @param b
     * @return true:a 比 b 高 ,输出;false a <= b,压栈
     * a 必须为栈顶
     */
    private static boolean compare(char a,char b){
        if ((a=='+'||a=='-')){
            return false;
        }
        return true;
    }


}

运算结果:

后缀表达式:[1.0, 2.0, 3.0, *, 10.0, 2.0, /, -, +]
计算过程:2.0*3.0
计算过程:10.0/2.0
计算过程:6.0-5.0
计算过程:1.0+1.0
计算结果:2.0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值