用栈实现多位数综合计算器(位数不限)

在跟着韩老师学习数据结构,在栈这一章中,有个综合计算器,觉得老师的代码可以再稍微优化一下。我用到了集合,先将运算字符串做了转换,这样计算就不会被数字的位数限制了。代码如下,请多指教。

创建栈

package com.m.demo6;

import java.util.Arrays;

public class ArrayStack {
	private int maxsize;
	private int [] array;
	private int top;
	public ArrayStack(int maxsize) {
		
		this.maxsize = maxsize;
		this.array=new int[maxsize];
		this.top=-1;
	}
	public boolean isFull() {
		return top==maxsize-1;
	}
	
	public boolean isEmpty() {
		return top==-1;
	}
	public void push(int i) {
		if(isFull()) {
			System.out.println("栈满");
			return;
		}
		top++;
		array[top]=i;
	}
	public int pop() {
		if(isEmpty()) {
			System.out.println("栈空");
			return -1;
		}
		int temp=array[top];
		top--;
		return temp;
	}
//	打印top
	public int peek() {
		if(isEmpty()) {
			System.out.println("栈空");
//			return -1;
		}
//		System.out.println(array[top]);
		return array[top];
		
	}
	@Override
	public String toString() {
		return "ArrayStack [array=" + Arrays.toString(array) + "]";
	}

	
}

实现计算器

package com.m.demo6;

import java.util.ArrayList;
import java.util.List;

public class MyCounter {
		public static void main(String[] args) {
			ArrayStack stackNum=new ArrayStack(10);//用来存放数字
			ArrayStack stackOp=new ArrayStack(10);//用来存放运算符 char 和int 可以混用
			String str="8888*234+12-5";
//			String str="3+2*6-2";
			List<String> li=numsMerge(str);
//			将字符串型转为integer型
			List<Integer> list=String2Integer(li);
			/**
			 * 1. 通过一个 index 值(索引),来遍历我们的表达式 
			 * 2. 如果我们发现是一个数字, 就直接入数栈 
			 * 3. 如果发现扫描到是一个符号, 就分如下情况
			 * 3.1 如果发现当前的符号栈为 空,就直接入栈 
			 * 3.2 如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符,
			 * 就需要从数栈中pop出两个数,在从符号栈中pop出一个符号,进行运算,将得到结果,入数栈,然后将当前的操作符入符号栈,
			 * 如果当前的操作符的优先级大于栈中的操作符, 就直接入符号栈. 
			 * 4. 当表达式扫描完毕,就顺序的从 数栈和符号栈中pop出相应的数和符号,并运行. 
			 * 5.最后在数栈只有一个数字,就是表达式的结果
			 * 
			 */
//			遍历集合分别入栈:
			for(int i:list) {
				if(isOption(i)) {
//					
//					3.1如果发现当前的符号栈为 空,就直接入栈
					if(stackOp.isEmpty()) {
						stackOp.push(i);
					}else {
//						3.2 如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符,
						 //* 就需要从数栈中pop出两个数,在从符号栈中pop出一个符号,进行运算,将得到结果,入数栈,然后将当前的操作符入符号栈,
						// * 如果当前的操作符的优先级大于栈中的操作符, 就直接入符号栈. 
						if(opPriperty(i)<=opPriperty(stackOp.peek())) {
							int num1=stackNum.pop();
							int num2=stackNum.pop();
							int op=stackOp.pop();
							int res=result(num1,num2,op);
							stackNum.push(res);
							stackOp.push(i);
							
						}else {
							stackOp.push(i);
						}
						
					}
					
				}else {
					//如果我们发现是一个数字, 就直接入数栈:将字符串先转换为数字入数栈
					stackNum.push(i);
//					stackNum.peek();
					
				}
			}

//			4. 当表达式扫描完毕,就顺序的从 数栈和符号栈中pop出相应的数和符号,并运行. 
//			System.out.println(stackNum);
//			System.out.println(stackOp);
			while(true) {
				if(stackOp.isEmpty()) {
					break;
				}
				int num1=stackNum.pop();
				int num2=stackNum.pop();
				int op=stackOp.pop();
				int res=result(num1,num2,op);
				stackNum.push(res);
				
			}
			System.out.printf("%s=%d\n",str,stackNum.peek());
			
		}
		
		
		
		
		
		
		
		/**
		 * 这个方法是将字符串中的数字合并,方便之后直接运用
		 * @param str 输入原始字符串
		 * @return	将字符串和符号分开后返回 方便实现多位数的运算
		 */
		public static List<String> numsMerge(String str){
//			String s="723+5*7890+123";
			char[] chs=str.toCharArray();
			List<String> list=new ArrayList<>();
			String ss="";
			for(int i=0;i<chs.length;i++) {
				
				if(chs[i]=='+'||chs[i]=='-'||chs[i]=='*'||chs[i]=='/') {
//					System.out.println(ss);
					list.add(ss);
					list.add(String.valueOf(chs[i]));
					ss="";
				}else {
					ss+=chs[i];
				}
				
				
			}
//			System.out.println(ss);
			list.add(ss);
//			System.out.println(list);
			return list;
		}
		/**
		 * 遍历集合,将元素转为int 类型,java中int 类型和char类型可以混用
		 * @param list
		 * @return
		 */
		public static List<Integer> String2Integer(List<String> list){
//			System.out.println(list);
			List<Integer> list2=new ArrayList<>();
			for(String li:list) {
				int i=0;
//				System.out.println("li长度:"+li.length());
//				System.out.println("li==*:"+(li.equals("*")));
				if(li.equals("+")||li.equals("-")||li.equals("*")||li.equals("/")) {
					i=li.charAt(0);
				}else {
					i=Integer.parseInt(li);
				}
				list2.add(i);
			}
//			System.out.println(list2);
			return list2;
		}
		/**
		 * 判断是否为操作符
		 * @param li
		 * @return
		 */
		public static boolean isOption(int li) {
			return li=='+'||li=='-'||li=='*'||li=='/';
		}
		/**
		 * op运算
		 * @param num1
		 * @param num2
		 * @param op
		 * @return
		 */
		public static int result(int num1,int num2,int op) {
			int res=0;
			switch(op) {
			case '+':res=num1+num2;break;
			case '-':res=num2-num1;break;
			case '*':res=num2*num1;break;
			case '/':res=num2/num1;break;
			default:break;
			}
			return res;
		}
		public static int opPriperty(int op) {
			if(op=='+'||op=='-') {
				return 0;
			}
			return 1;
		}
		
}

在这里插入图片描述

一、进制转换 输入 10进制:直接输入,支持负数。 16进制:0x10,不支持负数 浮点数:直接收入,支持负数。 字符:'A',字符必须用两个单引号。 =================================================================================================== 二、表达式计算 1.支持大数运算。大数用数组表示,数组大小为1000个元素。最大能计算499的阶层。 大数表示方法: sign,intcount,decimalcount|num[PBigNum_ValueLength]。 sign: 符号。正数:sign=0; 负数:sign=1。 intcount: 整数个数。 decimalcount: 小数个数。 num: __int64数组,元素个数=PBigNum_ValueLength。 举例1: 0,3,0|0,0,0,0,0,0,0,1,2,3代表123。(假设PBigNum_ValueLength=10) 举例2: 1,3,2|0,0,0,0,0,1,2,3,4,5代表-123.45。 举例3: 0,1,0|0,0,0,0,0,0,0,0,0,0代表0。 举例4: 0,1,0|0,0,0,0,0,0,0,0,0,1代表1。 举例5: 0,0,1|0,0,0,0,0,0,0,0,0,1代表0.1。 举例6: 0,0,0|0,0,0,0,0,0,0,0,0,0 此数非法 特点: sign,intcount,decimalcount,num[]均不可能出现负数;sign取值0与1;intcount和decimalcount不可能同时是0。 --------------------------------------------------------------------------------------------------- 2.支持四则运算,支持括号,支持负数,支持双精度浮点数double。 支持+-*/。运算数以数组表示,并模拟+-*/,并没有直接调用C/C++当中的+-*/运算符对两个运算数进行运算。 3.支持以下字符串运算:"123+-456","123--456"。不支持以下字符串运算:"123++456","123-+456"。 4.小数点精度20位。 ------------------------------------------------- 5.测试用例: 1/6=0.16666666666666666667 3175/6=529.16666666666666666667 1/7=0.14285714285714285714 1+(2)=3 1+(-2)=-1 0xFF+1=256 0xFFFFFFFFFFFFFFFF*0xFFFFFFFFFFFFFFFF=340282366920938463426481119284349108225 -0x123*-0x123=84681 0xFFFFFF+0=16777215 0xFFFFFF*0=00000000 10.569*2.469=26.094861 12.5+13.5=26 12.5/13.5=0.92592592592592592593 56*0=0 (((952.5*400/25.4)*1024*2)/1024/1024)/8=3.662109375 100!=93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 0.7*0.15=0.105 ------------------------------------------------- 7.支持函数 1.fac 输入fac(449)。最大参数449。结果有998位。 2.pow
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值