package stack;
import org.junit.Test;
//栈实现计算器
public class Calculator {
@Test
public void test(){
//3+2*6-4
//定义一个数栈 和一个字符栈
ArrayStack2 numberStack=new ArrayStack2(10);
ArrayStack2 operaStack=new ArrayStack2(10);
//定义接受的值
int num1=0;
int num2=0;
int opera=0; //操作符 可以用char
int res=0; //返回结果
int index=0;//定义一个辅助指针
String str="100000+1000*2000-50000"; //多为数的问题 思路计算利用keepStr来保存这些多位数
//字符串是以\0结尾
System.out.println("str长度:"+str.length());
String keepNum="";
char ch=' ';//分词扫描得到的cahr 保存到ch
while(true){
ch=str.subSequence(index, index+1).charAt(0); //截取str的字符
//判断是不是操作符
if(operaStack.isOpera(ch)){
//再判断 符号栈里是不是有操作符 如果没有直接入栈,有再判断符号优先级
if(operaStack.isEmpty()){
operaStack.push(ch);
}else {
//和前一个操作栈里的字符进行优先级判断
//如果当前优先级大于前一个
if(operaStack.priority(ch)>operaStack.priority(operaStack.peek())){
operaStack.push(ch);
}else{
//当前的优先级小于之前的优先级
//那么从数字栈中取出两个值,操作栈中取出一个值进行计算。计算的值再入数字栈,再把当前操作符入字符栈
num1=numberStack.pop();
num2=numberStack.pop();
opera=operaStack.pop();
res=numberStack.cal(num1, num2, opera);
numberStack.push(res);
operaStack.push(ch); //当前操作符ch入字符栈
}
}
//如果是数字
}else{
//定义一个字符串来拼接数字
keepNum+=ch;
//判断多位数,判断下一个字符是不是数字,如果是最后一个数字了,就直接入栈
if(index==str.length()-1){
numberStack.push(Integer.parseInt(keepNum));
}else{
//判断下一个字符是不是数字,如果是数字就继续扫描,keepNum拼接,如果是运算符就入栈
if(operaStack.isOpera(str.substring(index+1,index+2).charAt(0))){
numberStack.push(Integer.parseInt(keepNum));
keepNum="";
}
}
// numberStack.push(ch-48);//因为字符'1'=48+1 ASCll码
}
index++; //往下遍历
if(index>=str.length()){
break; //遍历到最后一个字符后就退出程序
}
}
//然后进行数字栈,符号栈遍历,如果符号栈遍历完之后,那么数字栈中就只有最后一个返回值了
while(true){
if(operaStack.isEmpty()){
break;
}
num1=numberStack.pop();
num2=numberStack.pop();
opera=operaStack.pop();
res=numberStack.cal(num1, num2, opera);
numberStack.push(res);
}
System.out.printf("表达式%s=%d",str,numberStack.pop());
}
}
//数组模拟栈
class ArrayStack2{
private int maxSize;//栈的最大值
private int top=-1; //栈指向
private int[] stack;//模拟栈数组
public ArrayStack2(int maxSize) {
this.maxSize = maxSize;
stack=new int[maxSize];
}
//偷看栈顶的值
public int peek(){
return stack[top];
}
//判断栈满
public boolean isFull(){
return top==maxSize-1; //top->最顶部
}
//判断栈空
public boolean isEmpty(){
return top==-1;
}
//入栈 push 往数组里添加数据 先判断栈是否满了
public void push(int value){
if(isFull()){
System.out.println("栈满了~ ~");
return;
}
top++;
stack[top]=value;
}
//出栈 pop 先进后出 顶部先出 先判断栈是否为空
public int pop(){
if(isEmpty()){
throw new RuntimeException("栈空~ ~");
}
int value=stack[top];
top--;
return value;
}
//遍历栈
public void list(){
//先判断栈是否为空
if(isEmpty()){
System.out.println("栈空~ ~");
return;
}
//先进后出 从最后往前遍历
for (int i =top; i>=0 ; i--) {
System.out.printf("stack[%d]=%d\n",i,stack[i]);
}
}
//返回运算符的优先级,优先级是程序员来定义的,优先级用数字来表示
//数字越大,则优先级越高
public int priority(int opera){
if(opera=='*'||opera=='/'){
return 1;
}else if(opera=='+'||opera=='-') {
return 0;
}else {
return -1; //假设当前的表达式只有+ - * /
}
}
//判断是不是一个运算符
public boolean isOpera(char val){
return val=='*'||val=='/'||val=='+'||val=='-';
}
//计算方法
public int cal(int num1,int num2,int opera){
int res=0; //用于计算的结果
switch (opera){
case '+':
res=num1+num2;break;
case '-':
res=num2-num1;break; //stack是先进后出
case '*':
res=num1*num2;break;
case '/':
res=num2/num1;break;
default:
break;
}
return res;
}
}
栈实现+ - * / 简单的综合计算器
最新推荐文章于 2024-07-09 18:04:44 发布