栈
Stack<String> stack = new Stack<String>();
stack.push("num1"); //入栈
stack.peek(); //查看栈顶元素
while (stack.size() > 0) //栈不为空
{
System.out.println(stack.pop()); //输出出栈元素
}
小计算器实例
例如:(15-2*4+1)/2
1、分割字符串存入List集合:[(, 15, -, 2, *, 4, +, 1, ), /, 2]
2、中缀表达式转后缀表达式
(1) 中缀表达式集合:[(, 15, -, 2, *, 4, +, 1, ), /, 2];
(2)后缀表达式集合:[15, 2, 4, *, -, 1, +, 2, /];
(3) 初始化栈stack,初始化集合list,参数中缀表达式集合value;
(4)遍历value
1)遇到整数,直接加入到list;
2)遇到 “(”,直接压栈stack;
3)遇到 “)”,不断把栈stack顶元素取出加入到list直到栈stack顶元素是“(”,最后把栈stack顶“(”弹出;
4)遇到运算符,如果栈stack顶元素优先级 >= 该运算符优先级,把栈stack顶元素取出加入到list,该运算符 继续与栈stack顶元素进行比较,直到stack顶元素优先级 < 该运算符优先级就把运算符压入栈stack;
当栈stack为空,直接压入栈stack;
当栈stack顶元素是左括号时,直接压入栈stack;
(5)遍历完value,如果栈stack还有元素,把栈stack元素出栈加入到list中;
3、根据后缀表达式进行计算 [15, 2, 4, *, -, 1, +, 2, /]
(1) 初始化栈stack
(2)遍历后缀表达式集合
1)遇到整数,压入栈stack;
2)遇到运算符,弹出栈stack顶两个整数进行计算,再把结果压入到栈stack;
class Calculation
{
private int MUL = 2; //乘法优先级
private int DIV = 2; //除法优先级
private int ADD = 1; //加法优先级
private int SUB = 1; //减法优先级
private int OTHER = 0; //其它符号
private String value; //需要求值的表达式
public Calculation(String value) //构造函数
{
this.value = value;
}
public int getResult() //返回计算结果
{
return calculate(infixToSuffix(splitString(value)));
}
private int operatorPrecedence(String value) //返回运算符优先级
{
if (value.equals("*"))
{
return MUL;
}
else if (value.equals("/"))
{
return DIV;
}
else if (value.equals("+"))
{
return ADD;
}
else if (value.equals("-"))
{
return SUB;
}
else
{
return OTHER; //当传过来的字符串是“(”或其它不合理符号
}
}
private List<String> splitString(String value) //对字符串进行分割,返回集合
{
List<String> list = new ArrayList<String>(); //初始化一个集合
int index = 0;
int len = value.length(); //字符串长度
while (index < len) //遍历字符串
{
String num = "";
char c = value.charAt(index);
if (c >= 49 && c <= 57) //遇到整数,1~9的ASCII码为49~57
{
do //处理多位数情况
{
num += c;
index++;
}
while(index < len && (c = value.charAt(index)) >= 49 && c <= 57);
list.add(num); //添加数据到集合
}
else //遇到运算符
{
list.add("" + c); //c要先转成字符串
index++;
}
}
return list; //返回集合
}
private List<String> infixToSuffix(List<String> value) //中缀表达式转后缀表达式
{
Stack<String> stack = new Stack<String>(); //初始化栈
List<String> list = new ArrayList<String>(); //初始化集合
for (String item: value) //遍历传过来的value集合
{
if (item.matches("\\d+")) //遇到整数,直接加入到list
{
list.add(item);
}
else if (item.equals("(")) //遇到 “(”,直接压栈stack
{
stack.add(item);
}
else if (item.equals(")")) //遇到 “)”
{
while (!stack.peek().equals("("))
//不断把栈stack顶元素取出加入到list直到栈stack顶元素是“(”
{
list.add(stack.pop());
}
stack.pop(); //最后把栈stack顶“(”弹出
}
else //遇到运算符
{
//循环比较是否栈stack顶元素优先级 >= 该运算符优先级
//栈stack为空或者栈stack顶元素是左括号时直接退出循环
while (stack.size() > 0
&& operatorPrecedence(stack.peek()) >= operatorPrecedence(item))
{
list.add(stack.pop()); //把栈stack顶元素取出加入到list
}
stack.push(item); //把运算符压入栈stack
}
}
//如果栈stack还有元素,把栈stack元素出栈加入到list中
while (stack.size() > 0)
{
list.add(stack.pop());
}
return list;
}
private int calculate(List<String> value) //根据后缀表达式进行计算
{
Stack<String> stack = new Stack<String>(); //初始化栈
for(String item: value) //遍历集合
{
if (item.matches("\\d+")) //遇到整数,压入栈stack
{
stack.add(item);
}
else //遇到运算符,弹出栈stack顶两个整数进行计算,再把结果压入到栈stack
{
int num2 = Integer.parseInt(stack.pop()); //第一个弹出的整数
int num1 = Integer.parseInt(stack.pop()); //第二个弹出的整数
int res = 0;
if (item.equals("+"))
{
res = num1 + num2;
}
else if (item.equals("-"))
{
res = num1 - num2; //第二个弹出的整数减去第一个弹出的整数
}
else if (item.equals("*"))
{
res = num1 * num2;
}
else if (item.equals("/"))
{
res = num1 / num2; //第二个弹出的整数除以第一个弹出的整数
}
else
{
System.out.println("运算符有问题!");
return 0;
}
stack.add("" + res);
}
}
return Integer.parseInt(stack.pop());
}
}
PS:加减乘除且有括号的整数运算
不处理空格或其他符号,不处理小数