2020-06-20数据结构与算法之栈实现科学计数器
只能用于单位数
import java.util.*;
import java.util.Stack;
public class Calculator {
public static void main(String[] args) {
//根据思路,完成表达式的思路
String expression = "3+2*6-2";
//创建两个栈,数栈和符号栈
arraystacked1 stack1 = new arraystacked1(10);
arraystacked1 stack2 = new arraystacked1(10);
int index = 0; //用于扫描
int num1 = 0;
int num2 = 0;
int oper = 0;
int res = 0;
char ch = ' '; //将每次扫描得到的符号放到ch中
// 用while扫描
while (true) {
ch = expression.substring(index, index + 1).charAt(0);
//判断ch是什么
if (stack2.isOper(ch)) { //如果ch是字符
if (!stack2.isEmpty()) { //并且stack2不为空
//如果当前符号的优先级小于或等于栈顶符号的优先级, 则取出两数相加,然后把值放进数栈中
if (stack2.priorty(ch) <= stack2.priorty(stack2.peek())) {
num1 = stack1.pop();
num2 = stack1.pop();
oper = stack2.pop();
res = stack1.cal(num1, num2, oper); //取出数据执行操作
stack1.push(res); //结果放在数据栈中
stack2.push(ch); //符号放在符号栈中
} else {
//如果大于直接入栈
stack2.push(ch);
}
} else {
stack2.push(ch); //如果符号栈为空,直接进栈
}
} else {
stack1.push(ch-48); //把字符串根据ascii码转化为数值
}
index++; //索引指向下一个值
if (index >= expression.length()) {
break;
} //如果遍历完成,就跳出循环
}
while (!stack2.isEmpty()) {
/* if (stack2.isEmpty()) { //如果符号栈为空,数栈只有一个数
break;
}*/
num1 = stack1.pop();
num2 = stack1.pop();
oper = stack2.pop();
res = stack1.cal(num1, num2, oper);
// System.out.printf("表达式的值为%d:", res);
stack1.push(res);
}
// int s=stack1.pop();
// System.out.printf("表达式的值为:", expression, s);
System.out.println(stack1.pop());
}
}
//先创建一个栈
class arraystacked1 {
private int maxSize; //栈的最大容量
private int[] stack1; //数组模拟栈
private int top = -1; //初始化栈顶
public arraystacked1(int maxSize) {
this.maxSize = maxSize;
stack1 = new int[this.maxSize];
}
public boolean isFull() {
return top == maxSize - 1;
}
public boolean isEmpty() {
return top == -1;
}
//进站操作
public void push(int value) {
if (isFull()) {
System.out.println("栈已满,无法添加数据!");
return;
} else {
top++;
stack1[top] = value;
}
}
//出栈操作
public int pop() {
if (isEmpty()) {
throw new RuntimeException("栈空,没有数据!");
}
int va=stack1[top];
top--;
return va;
}
// 遍历栈需要从栈顶开始显示数据
public void showStack() {
if (isEmpty()) {
System.out.println("栈为空,没有数据!");
}
while (true) {
if (top >= 0) {
System.out.printf("stack[%d]=%d\n", top, stack1[top]);
top--;
}
}
}
// 返回运算符的优先级,优先级由程序员来定义,数字越大,优先级越高
public int priorty(int oper) {
if (oper == '*' || oper == '/') {
return 1;
} else if (oper == '+' || oper == '-') {
return 0;
} else {
return -1;
}
}
//判断是不是运算符
public boolean isOper(int val) {
return val == '*' || val == '/' || val == '+' || val == '-';
}
//计算方法
public int cal(int num1, int num2, int oper) {
int result = 0; //返回结果为result
//注意的是num2才是后出来的那个数,num1是先的那个数
switch (oper) {
case '+':
result = num1 + num2;
break;
case '-':
result = num2- num1;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num2 / num1;
break;
default:
break;
}
return result;
}
//增加一个方法,可以看到栈顶的值,但不弹出
public int peek() {
return stack1[top];
}
}
修改版:
import java.util.*;
import java.util.Stack;
public class Calculator {
public static void main(String[] args) {
//根据思路,完成表达式的思路
String expression = "13+2*6-2";
//创建两个栈,数栈和符号栈
arraystacked1 stack1 = new arraystacked1(10);
arraystacked1 stack2 = new arraystacked1(10);
int index = 0; //用于扫描
int num1 = 0;
int num2 = 0;
int oper = 0;
int res = 0;
char ch = ' '; //将每次扫描得到的符号放到ch中
String KN="";
// 用while扫描
while (true) {
ch = expression.substring(index, index + 1).charAt(0);
//判断ch是什么
if (stack2.isOper(ch)) { //如果ch是字符
if (!stack2.isEmpty()) { //并且stack2不为空
//如果当前符号的优先级小于或等于栈顶符号的优先级, 则取出两数相加,然后把值放进数栈中
if (stack2.priorty(ch) <= stack2.priorty(stack2.peek())) {
num1 = stack1.pop();
num2 = stack1.pop();
oper = stack2.pop();
res = stack1.cal(num1, num2, oper); //取出数据执行操作
stack1.push(res); //结果放在数据栈中
stack2.push(ch); //符号放在符号栈中
} else {
//如果大于直接入栈
stack2.push(ch);
}
} else {
stack2.push(ch); //如果符号栈为空,直接进栈
}
} else {
// stack1.push(ch-48); //把字符串根据ascii码转化为数值
//当处理是多位数时,不能发现数就立即入栈
//用index再进行扫描,如果后面是数就进行拼接,如果是字符就直接入栈
//因此要定义一个变量字符串
KN += ch; //拼接操作符
if(index==expression.length()-1) {
stack1.push(Integer.parseInt(KN));
}else {
if(stack2.isOper(expression.substring(index+1, index + 2).charAt(0))) {
stack1.push(Integer.parseInt(KN));
KN="";
}
}
}
index++; //索引指向下一个值
if (index >= expression.length()) {
break;
} //如果遍历完成,就跳出循环
}
while (!stack2.isEmpty()) {
/* if (stack2.isEmpty()) { //如果符号栈为空,数栈只有一个数
break;
}*/
num1 = stack1.pop();
num2 = stack1.pop();
oper = stack2.pop();
res = stack1.cal(num1, num2, oper);
// System.out.printf("表达式的值为%d:", res);
stack1.push(res);
}
// int s=stack1.pop();
// System.out.printf("表达式的值为:", expression, s);
System.out.println(stack1.pop());
}
}
//先创建一个栈
class arraystacked1 {
private int maxSize; //栈的最大容量
private int[] stack1; //数组模拟栈
private int top = -1; //初始化栈顶
public arraystacked1(int maxSize) {
this.maxSize = maxSize;
stack1 = new int[this.maxSize];
}
public boolean isFull() {
return top == maxSize - 1;
}
public boolean isEmpty() {
return top == -1;
}
//进站操作
public void push(int value) {
if (isFull()) {
System.out.println("栈已满,无法添加数据!");
return;
} else {
top++;
stack1[top] = value;
}
}
//出栈操作
public int pop() {
if (isEmpty()) {
throw new RuntimeException("栈空,没有数据!");
}
int va=stack1[top];
top--;
return va;
}
// 遍历栈需要从栈顶开始显示数据
public void showStack() {
if (isEmpty()) {
System.out.println("栈为空,没有数据!");
}
while (true) {
if (top >= 0) {
System.out.printf("stack[%d]=%d\n", top, stack1[top]);
top--;
}
}
}
// 返回运算符的优先级,优先级由程序员来定义,数字越大,优先级越高
public int priorty(int oper) {
if (oper == '*' || oper == '/') {
return 1;
} else if (oper == '+' || oper == '-') {
return 0;
} else {
return -1;
}
}
//判断是不是运算符
public boolean isOper(int val) {
return val == '*' || val == '/' || val == '+' || val == '-';
}
//计算方法
public int cal(int num1, int num2, int oper) {
int result = 0; //返回结果为result
//注意的是num2才是后出来的那个数,num1是先的那个数
switch (oper) {
case '+':
result = num1 + num2;
break;
case '-':
result = num2- num1;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num2 / num1;
break;
default:
break;
}
return result;
}
//增加一个方法,可以看到栈顶的值,但不弹出
public int peek() {
return stack1[top];
}
}