大话数据结构——使用栈实现简单的四则运算

最近在读《大话数据结构》,里面有个例子是使用栈实现四则运算,现在我用java把这个功能实现试试

代码如下:

package com.datastruct;

import java.util.ArrayList;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StackPractice {

	private static ArrayList<String> symbolList;
	static{
		symbolList = new ArrayList<>();
		symbolList.add(SymbolEnum.ADD.getVal());
		symbolList.add(SymbolEnum.SUBTRACT.getVal());
		symbolList.add(SymbolEnum.MULTIPLY.getVal());
		symbolList.add(SymbolEnum.DIVIDE.getVal());
		symbolList.add(SymbolEnum.LEFT_BRACKET.getVal());
		symbolList.add(SymbolEnum.RIGHT_BRACKET.getVal());
	}

	public static void main(String[] args) {
		String exp = "9+(3-1)*3+10/2";
		try {
			String exp2 = convertExp(exp);
			System.out.println(cal(exp2));
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}

	private static boolean isNumeric(String str){
		   Pattern pattern = Pattern.compile("[0-9]*");
		   Matcher isNum = pattern.matcher(str);
		   if( !isNum.matches() ){
		       return false;
		   }
		   return true;
		}

	/**
	 * 计算后缀表达式值
	 * @return
	 */
	private static int cal(String exp){
		String[] expArr = exp.split(" ");
		Stack<String> calStack = new Stack<String>();
		for(int i=0;i<expArr.length;i++){
			String tmp = expArr[i];
			if(isNumeric(tmp)){//数字入栈
				calStack.push(tmp);
			}else{
				int num1 = Integer.parseInt(calStack.pop());//栈顶弹出1
				int num2 = Integer.parseInt(calStack.pop());//栈顶弹出2
				switch (tmp) {
				case "-":
					calStack.push(num2 - num1 + "");
					break;
				case "+":
					calStack.push(num2 + num1 + "");
					break;
				case "*":
					calStack.push(num2 * num1 + "");
					break;
				case "/":
					calStack.push(num2 / num1 + "");
					break;
				default:
					break;
				}
			}
		}
		return Integer.parseInt(calStack.pop());
	}

	/**
	 * 中缀表达式转为后缀表达式
	 * @return
	 */
	private static String convertExp(String exp) throws Exception{
		//字符串转数组
		char[] expArr = exp.toCharArray();
		StringBuffer sb = new StringBuffer();
		Stack<String> symbolStack = new Stack<>();
		boolean isLastCharNumberFlag = true;
		for(int i = 0;i<expArr.length;i++){
			char curChar = expArr[i];
			//若为数字添加 若为符号则放入栈计算
			if(Character.isDigit(curChar)){
				if(isLastCharNumberFlag){
					sb.append(curChar);
				}else{
					sb.append(" ").append(curChar);
				}

				isLastCharNumberFlag = true;
			}else if(symbolList.contains(String.valueOf(curChar))){//符号
				//
				String symbol = String.valueOf(curChar);
				if(SymbolEnum.RIGHT_BRACKET.getVal().equals(symbol)
						)
				{

					//如果是右括号,得匹配左括号
					String symbolStr = symbolStack.pop();
					while(!SymbolEnum.LEFT_BRACKET.getVal().equals(symbolStr)){
						sb.append(" ").append(symbolStr);
						symbolStr = symbolStack.pop();
					}
					isLastCharNumberFlag = false;
					continue;
				}else if(SymbolEnum.DIVIDE.getVal().equals(symbol) ||
						SymbolEnum.MULTIPLY.getVal().equals(symbol)	){
				}else{
					if(symbolStack.isEmpty()){
						symbolStack.push(symbol);
						continue;
					}
					String symbolStr = symbolStack.peek();
					if(SymbolEnum.DIVIDE.getVal().equals(symbolStr) ||
							SymbolEnum.MULTIPLY.getVal().equals(symbolStr)){
						while(!symbolStack.isEmpty()){
							sb.append(" ").append(symbolStack.pop());
						}
						symbolStack.push(symbol);
						isLastCharNumberFlag = false;
						continue;
					}
				}
				symbolStack.push(symbol);
				isLastCharNumberFlag = false;
			}
		}
		while(!symbolStack.isEmpty()){
			sb.append(" ").append(symbolStack.pop());
		}
		return sb.toString();
	}

	/**
	 * 运算符枚举
	 * @author Administrator
	 *
	 */
	enum SymbolEnum{
		ADD("+"), SUBTRACT("-"),MULTIPLY("*"),DIVIDE("/"),LEFT_BRACKET("("),RIGHT_BRACKET(")");
		private String val;

		public String getVal(){
			return val;
		}

		private SymbolEnum(String val){
			this.val = val;
		}
	}
}

  程序暂时有些bug,如表达式合法性没有校验,不能输入多个括号等

时间: 2024-10-03 22:15:31

大话数据结构——使用栈实现简单的四则运算的相关文章

数据结构之栈的简单应用(判断字符串中括号的合法性)

数据结构之栈(判断字符串中括号的合法性) 栈的定义 栈是一种线性数据结构,栈的特征是数据的插入和删除只能通过一端来实现,这一端称为"栈顶",相应的另一端称为"栈底":另外其还有先进后出,后进先出的特征. 栈是一种高效的数据结构,因为数据只能在栈的顶端添加或者删除,所以这样的操作很快而且容易实现. 说到线性结构,得先了解一下数据的逻辑结构,数据的逻辑结构分为线性结构.集合结构.树形结构和图形结构,如下图所示,栈是一种特殊的线性表,是线性结构的一种. JavaScrip

大话数据结构之栈的链式存储结构

#include<iostream> //#include<time.h> //#include <stdlib.h> using namespace std; #define OK 1 #define TRUE 1 #define FALSE 0 #define ERROR 0 typedef int status;//返回的状态值 typedef int elemtype;//节点里数据的类型 //每一个节点的数据结构 typedef struct stacknod

大话数据结构之栈的顺序存储结构

#include<iostream> //#include<time.h> //#include <stdlib.h> using namespace std; #define OK 1 #define TRUE 1 #define FALSE 0 #define ERROR 0 #define MAXSIZE 100//数组的最大大小 typedef int status;//返回的状态值 typedef int elemtype;//节点里数据的类型 typedef

大话数据结构之栈的链的应用--递归值菲涅数列

#include<iostream> using namespace std; #define OK 1 #define TRUE 1 #define FALSE 0 #define ERROR 0 typedef int status;//返回的状态值 //波斐数列,某项的值为它的前两项的和 int fbi(int n) { if(n<2) { if(n==0) return 0; else return 1; } return fbi(n-1)+fbi(n-2); } int mai

(源代码见大话数据结构)栈的顺序存储结构——进栈&amp;出栈

#include <stdio.h>#include <time.h>#include <stdlib.h>#define MAXSIZE 1000#define OK 1#define ERROR 0#define TRUE 1#define FALS 0typedef int SElemType;typedef int Status;typedef struct{    SElemType data[MAXSIZE];    int top;}SqStack;Sta

【Java】 大话数据结构(6) 线性表之栈

本文根据<大话数据结构>一书,实现了Java版的栈的顺序存储结构.两栈共享空间.栈的链式存储机构. 栈:限定仅在表尾进行插入和删除操作的线性表. 栈的插入(进栈)和删除(出栈)操作如下图所示.   1.栈的顺序存储结构 用数组存放数据,top变量来指示栈顶元素在数组中的位置(栈顶指针).一个长度为5的栈的示意图如下: 实现程序: /** * 栈的顺序储存结构 * * 问题:构造器中,泛型数组创建是否有更好的方法? * @author Yongh * */ public class SqStac

简单数据结构之栈模拟

1 /************************************************************************************** 2 * Function : 模拟栈 3 * Create Date : 2014/04/23 4 * Author : NTSK13 5 * Email : [email protected] 6 * Copyright : 欢迎大家和我一起交流学习,转载请保持源文件的完整性. 7 * 任何单位和个人不经本人允许不得

链栈--(大话数据结构97页)

//链栈的实现 --大话数据结构99页 #include <iostream> using namespace std; //链节点定义 typedef struct stacknode { int data; struct stacknode * next; }StackNode, *LinkStackptr; //定义链栈,头指针 和 长度 struct LinkStack{ LinkStackptr top; int count; }; //初始化void InitStack(LinkS

【数据结构】栈和队列

栈和队列 容器数据结构是指一些包含了若干个其他相同或不同的数据结构的数据结构,被包含的这些每一个独立的数据结构都被称为一个元素,在一个容器中的元素往往支持相同的操作,具有类似的性质.之前说到过的线性表其实就是一种容器数据结构,本文中介绍的两种最常用的容器数据结构是栈和队列. 从功能上看,栈和队列大多用于计算过程中保存临时数据,这些数据是在计算过程中发现或产生的.在而后的计算中可能会用到这些数据.如果这些数据是固定的个数以及大小的话,可以构建几个变量来储存它们,但是如果这些数据不确定的话,就需要一