public class StackTool {
/**
* 判断括号是否匹配
* 如果是左括号就入栈,右括号则与栈顶元素匹配,如果匹配则删除栈顶元素
* @param expression
*/
public static void judge(String expression){
//模拟一个栈
char[] stack = new char[100];
int top = 0;
for(int i=0;i<expression.length();i++){
char val = expression.charAt(i);
//入栈操作
if(val=='('||val=='['||val=='{'){
stack[top++]=val;
}else if(val==')'){
//出栈前先判断栈中是否还有元素
if(top<=0||stack[--top]!='('){
System.out.println("match failed");
return;
}
}else if(val==']'){
if(top<=0||stack[--top]!='['){
System.out.println("match failed");
return;
}
}else if(val=='}'){
if(top<=0||stack[--top]!='{'){
System.out.println("match failed");
return;
}
}
}
System.out.println(top==0?"match success!":"match failed");
}
/**
* 计算后缀表达式,各个值用空格隔开
* 后缀表达式:不包含括号,运算符放在两个运算对象的后面,所有的计算按照运算符出现的顺序从左向右计算
* 例如:(2+1)*3 2 1 + 3 * (8-5)*(4-2) 8 5 - 4 2 - *
* @param expression
* @return
*/
public static double calSuffixExpression(String expression){
double[] stack = new double[100];
int top = 0;
String[] strs = expression.split(" ");
for(String str : strs){
if("+".equals(str)){
double first = stack[--top];
double second = stack[--top];
stack[top++] = first + second;
}else if("-".equals(str)){
double first = stack[--top];
double second = stack[--top];
stack[top++] = first - second;
}
else if("*".equals(str)){
double first = stack[--top];
double second = stack[--top];
stack[top++] = first * second;
}
else if("/".equals(str)){
double first = stack[--top];
double second = stack[--top];
stack[top++] = first / second;
}else{
stack[top++] = Double.parseDouble(str);
}
}
return stack[0];
}
/**
* 计算中缀表达式,中缀表达式就是一般的数学表达式
* 思路:如果后面的操作符比前面的操作符运算优先级高那么前面的操作符必须延迟计算,
* 如果后面的操作符运算优先级比前面的操作符低或者同级,那么前面的操作符就可以进行运算了
* 例子:a+b*c/d
* 首先将a入操作数栈,接着将+入操作符栈,接着b入操作数栈,此时还不能计算,还要看后面的操作符
* 接着将*入操作符栈,将c入操作数栈。此时碰到/号,与前面的*号同级,因此*号可以计算
* 将*出栈,将b,c出栈计算得到结果入操作数栈,将/号入操作符栈,将d入栈.此时表达式已经完毕
* 分析过程
* 操作数栈 操作符栈
* a a入栈
* a + +入栈
* a b + b入栈
* a b + * *入栈 *号优先级比+高,入栈
* a b c + * c入栈
* -------------------------------碰到/ /号与*号优先级相同 出栈计算
* a + b,c,*出栈 算b*c
* a b*c + / b*c,/入栈
* a b*c d + / d入栈 此时表达式完毕
* a + b*c,d,/出栈 算b*c/d
* a b*c/d + b*c/d入栈
* a,b*c/d,+出栈 算a+b*c/d得到结果
*
* -------------------------------------------------------
* 加强:带括号
* a*(b+c)----把括号里的内容就当做一个中缀表达式求值,并且左括号优先级最高使得前面的操作符不能运算
* 右括号优先级最低迫使括号里的操作符运算完
* @param expression
* @return
*/
public static double calInfixExpression(String expression){
double[] vals = new double[100];//操作数栈
int valTop = 0;
char[] ops = new char[100];//操作符栈
int opTop = 0;
String[] strs = expression.split(" ");
for(String str : strs){
if("+".equals(str)||"-".equals(str)){
//符号栈不为空
if(opTop>0){
int cnt = opTop-1;
char op = ops[cnt];//获取当前栈顶符号
//因为当前符号为+或者-,所以前面那个符号一定能够计算
if(op=='+'||op=='-'||op=='*'||op=='/'){
opTop--;
double second = vals[--valTop];
double first = vals[--valTop];
if(op=='+'){
vals[valTop++] = first + second;
}else if(op=='-'){
vals[valTop++] = first - second;
}else if(op=='*'){
vals[valTop++] = first * second;
}else if(op=='/'){
vals[valTop++] = first / second;
}
}
}
ops[opTop++] = str.charAt(0);//当前操作符入栈
}
else if("*".equals(str)||"/".equals(str)){
//符号栈不为空
if(opTop>0){
int cnt = opTop-1;
char op = ops[cnt];
//只有前面是*,/才可以计算
if(op=='*'||op=='/'){
opTop--;//可以计算将op出栈
double second = vals[--valTop];
double first = vals[--valTop];
if(op=='*'){
vals[valTop++] = first * second;
}else if(op=='/'){
vals[valTop++] = first / second;
}
}
}
ops[opTop++] = str.charAt(0);//当前操作符入栈
}
//优先级最高,前面的运算符不能计算
else if("(".equals(str)){
ops[opTop++] = str.charAt(0);
}
//碰到右括号,算完括号里的表达式内容
else if(")".equals(str)){
char op = ops[--opTop];
//如果出栈的符号是‘(’则说明表达式已经算完了
while(op!='('){
double second = vals[--valTop];
double first = vals[--valTop];
if(op=='+'){
vals[valTop++] = first + second;
}else if(op=='-'){
vals[valTop++] = first - second;
}else if(op=='*'){
vals[valTop++] = first * second;
}else if(op=='/'){
vals[valTop++] = first / second;
}
op = ops[--opTop];
}
}
else{
vals[valTop++] = Double.parseDouble(str);
}
}
//字符串处理完毕,栈中剩下的操作符和操作数中栈顶优先级大于栈底,依次出栈计算就可
while(opTop>0){
char op = ops[--opTop];
double second = vals[--valTop];
double first = vals[--valTop];
if(op=='+'){
vals[valTop++] = first + second;
}else if(op=='-'){
vals[valTop++] = first - second;
}else if(op=='*'){
vals[valTop++] = first * second;
}else if(op=='/'){
vals[valTop++] = first / second;
}
}
return vals[0];
}
}
运用栈对算数表达式求值
最新推荐文章于 2020-09-05 22:06:34 发布