zoukankan      html  css  js  c++  java
  • 使用链表栈实现计算器(+-*/)

    package 数据结构;


    import java.util.regex.Pattern;

    /**
    * @program: java_每天一题
    * @description: 使用单链表实现栈
    * 使用栈实现计算器:1,使用一个index遍历运算表达式字符串
    * 2,如果是数字,存入数字栈
    * 3.如果是字符,存入字符栈中
    * 3.1 如果当前字符栈是空栈,直接存入
    * 3.2如果当前字符栈是有操作符的,则进行操作优先级比较,
    * 如果当前操作符优先级小于或等于栈中操作符优先级,就需要从数栈中pop出两个数字,字符栈中pop一个字符,进行运算
    * 运算结果push进入数栈中,当前操作符存入字符栈中
    * 如果当前操作符优先级大于栈中操作符优先级,直接入栈
    * 4.当表达式index完毕,顺序弹出数栈及字符栈中的元素,进行运算
    * 5.当数栈中只有一个数字时,就是表达式的运算结果
    *
    * @author: czg
    * @create: 2020-05-15 12:07
    */
    public class j_栈_单链表 {

    public static void main(String[] args) {
    //中缀表达式 30+2*6-2
    String expression="(2+2)*3-2*2-1+(2*5+3+3)";

    System.out.println(calcExperssion(expression));

    }
    //计算
    public static double calcExperssion(String expression){
    if(expression==null||"".equals(expression)){
    throw new RuntimeException("中缀表达式错误!");
    }
    //括号处理
    while(expression.indexOf("(")>=0){
    int leftBra=expression.indexOf("(");
    int rightBra=expression.indexOf(")");
    String temp=expression.length()==rightBra?expression.substring(leftBra):expression.substring(leftBra+1,rightBra);
    double value = calcExperssion(temp);
    expression=new StringBuilder().append(expression.substring(0,leftBra))
    .append(String.valueOf(value)).append(expression.substring(rightBra+1)).toString();
    }

    //存放数字
    LinkedStack<Double> numStack=new LinkedStack();
    //存放运算符
    LinkedStack<String> operaStack=new LinkedStack();

    int index=0;
    double leftnum=0;//存放第二个弹出数字
    double rightnum=0;//存放一个弹出数字
    double answer=0; //运算答案
    String opera="";
    //循环取出全部表达式数据
    while (true){
    String data=getOneElement(expression,index);
    //如果运算符
    if(isOperator(data)){
    if(!operaStack.isEmpty()){
    while(operaPriority(data)<=operaPriority(operaStack.top.data)){
    //弹出top运算符
    opera=operaStack.pop().data;
    rightnum=numStack.pop().data;
    leftnum=numStack.pop().data;
    //得到运算结果
    double result=perform(leftnum,rightnum,opera);
    //将数据返回数栈中
    numStack.push(new StackNode<Double>(result));
    //data入栈
    if(operaStack.isEmpty()){
    break;
    }
    }
    operaStack.push(new StackNode<String>(data));

    }else {
    //空栈,直接入栈
    operaStack.push(new StackNode<String>(data));
    }
    }

    if(isInteger(data)){
    //将数据放入数栈中
    numStack.push(new StackNode(Double.parseDouble(data)));
    }
    //后移data长度(十位百位)位
    index=index+data.length();
    //移动到结尾时,结束循环
    if(index==expression.length()){
    break;
    }
    }
    System.out.println("--------------");
    operaStack.printStack();
    numStack.printStack();
    System.out.println("--------------");

    //顺序弹出数栈及字符栈中的元素,进行运算
    while(true){
    opera=operaStack.pop().data;
    rightnum=numStack.pop().data;
    leftnum=numStack.pop().data;
    //得到运算结果
    double result=perform(leftnum,rightnum,opera);
    //将数据返回数栈中
    numStack.push(new StackNode<Double>(result));

    if(numStack.getLength()==1){
    answer=numStack.pop().data;
    break;
    }
    }
    return answer;

    }

    //运算
    public static double perform(double left,double right,String opera){
    double result=0;
    switch (opera){
    case "+": result=left+right; break;
    case "-": result=left-right; break;
    case "*": result=right*left; break;
    case "/": result=left/right; break;
    default:
    throw new RuntimeException("运算符无法解析");
    }
    return result;
    }
    //获得一个元素
    public static String getOneElement(String experssion,int index){
    int count=index;
    String data="";
    while (true){
    String temp="";
    if(experssion.length()==count+1)
    {
    temp=experssion.substring(index);
    }else {
    temp=experssion.substring(index,count+1);
    }
    if(isOperator(temp)){
    data=temp;
    break;
    }
    if(isInteger(temp)||temp.equals(".")){
    data=temp;
    if(experssion.length()==count+1){
    break;
    }
    count++;
    }else if(data.length()>0){
    break;
    }
    }
    return data;
    }

    //判断字符串是否为数字
    public static boolean isInteger(String str) {
    try {
    new Double(str);
    return true;
    }catch (Exception e){
    return false;
    }
    }
    //判断是否是运算符
    public static boolean isOperator(String str){
    return "+-*/".indexOf(str)>=0;
    }
    //设置字符优先级
    public static int operaPriority(String opera){
    int result=0;
    switch (opera){
    case "+":
    case "-": break;
    case "*":
    case "/": result=1; break;
    default:
    throw new RuntimeException("运算符优先级无法解析");
    }
    return result;
    }
    }
    class LinkedStack<T>{
    //最上结点
    public StackNode<T> top;

    //判断是否为空
    public boolean isEmpty(){
    return top==null;
    }
    //入栈
    public void push(StackNode<T> node){
    if(top==null){
    top=node;
    return;
    }
    StackNode temp=top;
    top=node;
    top.next=temp;
    }

    //出栈
    public StackNode<T> pop(){
    if(isEmpty()){
    System.out.println("栈空");
    return null;
    }
    StackNode<T> temp=top;
    top=top.next;
    System.out.println("弹出值:"+temp.toString());
    return temp;
    }

    public int getLength(){
    if(isEmpty()){
    System.out.println("栈空");
    return 0;
    }
    int count=0;
    StackNode<T> temp=top;
    while (true){
    if(temp==null){
    break;
    }
    count++;
    System.out.println(temp.toString());
    temp=temp.next;
    }
    return count;
    }

    //打印栈
    public void printStack(){
    if(isEmpty()){
    System.out.println("栈空");
    return;
    }
    StackNode<T> temp=top;
    while (true){
    if(temp==null){
    break;
    }
    System.out.println(temp.toString());
    temp=temp.next;
    }
    }
    }
    class StackNode<T>{
    //结点数据
    public T data;
    //指向下一个结点
    public StackNode next;

    public StackNode(T data){
    this.data=data;
    }

    @Override
    public String toString() {
    String nextData=(next==null)?"null":String.valueOf(next.data);
    return "StackNode{" +
    "data=" + data +
    ", next=" + nextData +
    '}';
    }
    }
  • 相关阅读:
    MT【347】单变量求最值
    MT【346】拐点处分界
    MT【345】三个绝对值的和
    MT【344】构造函数
    MT【343】三数平方法
    MT【342】条件为非负实数
    MT【341】换元变形
    MT【340】彭塞列闭合定理
    MT【339】待定系数
    MT【338】分式变形
  • 原文地址:https://www.cnblogs.com/czgxxwz/p/12897942.html
Copyright © 2011-2022 走看看