栈类
package e_2;
/**
* 栈类
*/
public class ArrayStack<T> {
// 栈的大小
private int maxSize;
// 利用数组模拟栈
private Object[] stack;
// 栈顶指针
int top = -1;
// 构造函数
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
stack = new Object[this.maxSize];
}
// 判断栈满
public boolean isFull() {
return top == this.maxSize - 1;
}
// 判断栈空
public boolean isEmpty() {
return top == -1;
}
// 入栈
public void push(Object ele) {
// if (maxSize >= stack.length) {
// stack = Arrays.copyOf(stack,stack.length * 2);// 空间不足则扩容
// }
if (isFull()) {
System.out.println("栈溢出");
return;
}
top++;
stack[top] = ele;
}
// 出栈 (弹出并返回栈顶元素)
public T pop() {
if (isEmpty()) {
throw new RuntimeException("栈为空!");
}
Object value = stack[top];
top--;
return (T) value;
}
// 查看栈顶元素
public T peek() {
if (top == -1) {
throw new RuntimeException("栈为空!");
}
return (T) stack[top];
}
// 遍历栈
public void list() {
if (isEmpty()) {
System.out.println("栈为空!");
return;
}
System.out.println("top= " + top);
System.out.print("$ list $: ");
for (int i = top; i >= 0; i--) {
System.out.print(stack[top - i]+" ");
}
System.out.print("\n-------------------------\n");
}
}
操作字符表达式类
package e_2;
/**
* 操作字符表达式类
*/
public class OperationExpress {
//成员变量
String prefix_str;//保存前缀表达式
String postfix_str; //保存后缀表达式
//构造方法,传入一个String
public OperationExpress() {
}
/**
* eval将字符串当成有效的表达式 来求值 并 返回计算结果。。(作用于中缀表达式字符串)
*/
public float eval() {
//.....
return 1;
}
/**
* 中转后缀表达式方法。
*/
public String TranslateExpress(String str) {
ArrayStack<Character> stack = new ArrayStack<Character>(40);//初始化一个栈,存放运算符
StringBuffer sb = new StringBuffer();//存放
// String str="1-(1+2*3)/2";
stack.top = -1; //初始化栈 (top = -1表示栈空)
int i = 0;
char ch = str.charAt(i);//取str里单个的字符
while (true) {//不为空的字符,就依次扫描
System.out.println("i=" + i + " ch=" + ch);//---------
switch (ch) {
case '+':
case '-':
//优先级只大于'('
while (!stack.isEmpty() && stack.peek() != '(') {
sb.append(stack.pop());//出栈并加到缓存区
}
stack.push(ch);
break;
case '*':
case '/':
case '%':
//优先级小于'/*%'
// System.out.println("peek=" + stack.peek());
// stack.list();//=========
// System.out.println(stack.peek());
System.out.println(!stack.isEmpty());
while (!stack.isEmpty()) {
// System.out.println(stack.peek());// +
// System.out.println(!stack.isEmpty());
// System.out.println("s2");
if (stack.peek() == '/' || stack.peek() == '%' || stack.peek() == '*') {
sb.append(stack.pop());
} else {
break;
}
}
// 下面的while改成上面的while,java中不这样用,找这个bug所花时间:3小时
// while (!stack.isEmpty() && stack.peek() == '/' || stack.peek() == '%' || stack.peek() == '*') {
// sb.append(stack.pop());
// }
stack.push(ch);
break;
case '(':
stack.push(ch);
break;
case ')':
while (stack.peek() != '(') {
// System.out.println("/ 1"+stack.peek());
sb.append(stack.pop());
}
// System.out.println("/"+stack.peek());
stack.pop();//左括号出栈
// stack.top = -1;
break;
case ' ': //空格忽略
break;
default:
while (ch >= '0' && ch <= '9') {
sb.append(ch);
i++;
//赋值前判断,下标越界就跳出
if (i < str.length()) {
ch = str.charAt(i);
} else {
break;
}
}
i--;
sb.append(' ');//空格分割数字字符
}
stack.list();//========
i++;
//赋值前判断,下标越界就跳出
if (i < str.length()) {
ch = str.charAt(i);
} else {
break;
}
}
while (!stack.isEmpty()) {
sb.append(stack.pop());
}
// this.str = new String(sb);
String postfix = new String(sb);
this.postfix_str = postfix;
return postfix;
}
/**
* 计算后缀表达式。
*/
public double ComputeExpress(String postfix_str) {
ArrayStack<Double> stack = new ArrayStack<Double>(40);//初始化一个栈,存放操作数
double result = 0; //计算结果
double value; //计算转化的中间步
stack.top = -1; //初始化栈 (top = -1表示栈空)
int i = 0;
char ch = postfix_str.charAt(i);//取后缀字符串里单个的字符
while (true) {
if (ch != ' ' && ch >= '0' && ch <= '9') {//当前是数字字符
//方一
value = 0;
while (ch != ' ') {//由于数字后面都加了空格,如果下一个字符不是空格说明是两位以上的数字字符
value = value * 10 + ch - '0';
//相当于value=value*10+Integer.valueOf(ch);
i++;
if (i < postfix_str.length()) {
ch = postfix_str.charAt(i);
} else {
break;
}
}
System.out.println("**当前压入数字 " + value);//=======
stack.push(value);
// 方二:
// while (postfix_str.charAt(i + 1) != ' ') {
// value=value*10+Integer.valueOf(ch);
// i++;
// ch = postfix_str.charAt(i);
// }
// value=value*10+Integer.valueOf(ch);
// stack.push(value);
} else { //剩余是运算符与空格,是运算符调用calc()运算方法。空格忽略
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%') {
result = this.calc(ch, stack);//内部五则计算方法
// System.out.println("result = " + result);//=======
stack.push(result);
stack.list();//=======
}
i++;
if (i < postfix_str.length()) {
ch = postfix_str.charAt(i);
} else {
break;
}
}
}
if (stack.top != -1) {
result = stack.pop();
if (stack.top == -1) return result;
else {
System.out.println("出问题了");
// System.exit(0);
}
}
return result;
}
/**
* 内部五则计算方法
*/
private double calc(char op, ArrayStack stack) {
double result = 0;
double n1 = (double) stack.pop();
double n2 = (double) stack.pop();
switch (op) {
case '+':
result = n2 + n1;
break;
case '-':
result = n2 - n1;
break;
case '*':
result = n2 * n1;
break;
case '/':
result = n2 / n1;
break;
case '%':
result = n2 % n1;
break;
}
System.out.println(n2 + " " + op + " " + n1 + " = " + result);//=======
return result;
}
//展示
@Override
public String toString() {
return "OperationExpress{" +
"prefix_str='" + prefix_str + '\'' +
", postfix_str='" + postfix_str + '\'' +
'}';
}
}
入口
package e_2;
/**
* Name: xhm
* Method: java实现
* Project name: 实现一个简单的计算器,输入一个包含圆括号、加、减、乘、除、求余等符号组成的算术表达式字符串,输出该算术表达式的值。要求:
* (1)系统至少能实现加、减、乘、除、求余等运算;
* (2)利用栈的后进先出特性实现;
* (3)先将输入的算术表达式转换为后缀表达式,并输出后缀表达式;
* (4)利用后缀表达式输出表达式的计算结果。
*/
public class 计算器栈 {
public static void main(String[] args) {
String str ="(6-2)*5+(99%10+2)/2-7";
// String str ="1-(2+2*3)/2";
OperationExpress oe= new OperationExpress();//实例化操作字符表达式类
String postfix = oe.TranslateExpress(str);//调用方法,获得后缀表达式
double result = oe.ComputeExpress(postfix);
System.out.println("前缀表达式为:"+str);
System.out.println("后缀表达式为:"+postfix);
System.out.println("计算结果为:"+result);
}
}