使用链表栈实现计算器(+-*/)
Posted czgxxwz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用链表栈实现计算器(+-*/)相关的知识,希望对你有一定的参考价值。
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 +
‘}‘;
}
}
以上是关于使用链表栈实现计算器(+-*/)的主要内容,如果未能解决你的问题,请参考以下文章
[DataStructure]线性数据结构之稀疏数组链表栈和队列 Java 代码实现