中缀表达式
中缀表达式是一种常用的算术或逻辑公式表示方法,操作符一中缀形式处于操作数中间。中缀表达式是人们常用的算术表示方法。
虽然人的电脑很容易理解与分析中缀表达式,但对于计算机来说中缀表达式却很复杂的,因此计算表达式的值,通常需要先将中缀表达式转换为前缀或后缀表达式。
例如:3+5+7-8
前缀表达式
运算符位于操作数之前
例如:-++3578
后缀表达式:
运算符位于操作符之后
例如:
35+7+8-
将中缀表达式转为前缀表达式
- 初始化两个栈,一个运算符栈S1,一个存中间结果的栈S2
- 从右到左开始遍历表达式
- 遇到运算符,将其压入S1
- 如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈
- 否则,若优先级比栈顶运算符较高或者相等, 也将运算符压入S1
- 否则,将S1栈顶的元素压入到S2中,再次转到遇到运算符那一步
- 遇到操作数,将其压入S2
- 遇到括号的时候:
- 如果是右括号“)”,则直接压入S1
- 如果是左括号“(”,则一次弹出S1栈顶的运算符,并压入S2,直到遇到右括号“)”,此时,将这一对括号丢弃
- 重复2到5的步骤,直到表达式的最左边
- 将S1中剩余的运算符依次弹出并压入S2
- 依次弹出S2中的运算符并输出,结果即为中缀表达式对应的前缀表达式
Java代码:
public static String zhongzhui(String biaodashi){
String result = " ";
int i;
Stack<Character> S1 = new Stack<>();
Stack<Character> S2 = new Stack<>();
int provity = 0;
for(i = biaodashi.length()-1;i>=0;i--){
char temp = biaodashi.charAt(i);
if((temp >=48 && temp <=57 )|| temp == ')'){
if(temp != ')'){
S2.push(temp);
}else{
S1.push(temp);
provity = 0;
}
}else if(temp == '('){
char ch;
while((ch = S1.pop())!=')'){
S2.push(ch);
System.out.println(ch);
}
provity = getProvity(S1.peek());
System.out.println(provity);
}else if(S1.isEmpty() || S1.peek() == ')' || getProvity(S1.peek()) <= getProvity(temp)){
provity = getProvity(temp);
S1.push(temp);
System.out.println(temp);
}else{
while(provity> getProvity(temp)){
S2.push(S1.pop());
if(S1.isEmpty()){
break;
}
provity = getProvity(S1.peek());
}
S1.push(temp);
provity = getProvity(S1.peek());
}
}
while(!S1.isEmpty()){
S2.push(S1.pop());
}
StringBuilder s = new StringBuilder();
while(!S2.isEmpty()){
s.append(S2.pop());
}
result = s.toString();
return result;
}
public static int getProvity(char ch){
switch(ch){
case '+':
case '-':
return 1;
case 'x':
case '/':
return 2;
}
return 0;
}
例如 输入的表达式:”1+((2+3)×4)-5”
结果:-+1×+2345
ps:这段代码只能计算一位数的加减乘除,而且除不准确,想要进行多位数的,请自己修改。
计算机如何计算前缀表达式:
从右到左遍历前缀表达式,遇到数字,入栈,遇到运算符,弹出栈顶的两个元素,用运算符进行计算,将结果入栈。重复上述结果到遍历完成,最后栈中的结果就是表达式的结果
public static char GetResult(String qianzhui){
char result = ' ';
Stack<Character> S1 = new Stack<>();
int i ;
for(i = qianzhui.length()-1;i>=0;i--){
char temp = qianzhui.charAt(i);
if(temp>=48&&temp <=57){
S1.push(temp);
}else{
char num2 = S1.pop();
char num1 = S1.pop();
char num3=' ';
int t;
switch(temp){
case '+':
t= num2-48+num1-48;
num3 = (char)(t +48);
break;
case '-':
t = num2-48-(num1-48);
num3 = (char)(t +48);
break;
case 'x':
t = (num2-48)*(num1-48);
num3 = (char)(t +48);
break;
case '/':
t = (num2-48)/(num1-48);
num3 = (char)(t +48);
break;
}
S1.push(num3);
}
}
result = S1.pop();
return result;
}
中缀表达式转成后缀表达式
- 初始化两个栈:运算符栈S1,和操作数栈S2
- 从左到右遍历表达式
- 遇到操作数,压入S2
- 遇到运算符,比较与S1栈顶运算符的优先级:
- 如果S1为空,或者栈顶元素为左括号“(”,则直接压入S1
- 否则,若优先级比栈顶运算符高,直接压入S1
- 否则,将S1栈顶运算符弹出压入S2,再转到如果S1为空那一步
- 遇到括号的时候:
- 如果是左括号“(”,直接压入S1
- 如果是右括号,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号
- 重复2-5步,直到遍历完成
- 将S1中剩余的运算符压入S2
- S2中元素的逆序就是后缀表达式
public static String getHouzhui(String biaodashi){
String result = "";
int i;
Stack<Character> S1 = new Stack<>();
Stack<Character> S2 = new Stack<>();
int provity = 0;
for(i = 0; i<biaodashi.length();i++){
char temp = biaodashi.charAt(i);
System.out.println(temp+"yyyyy");
if((temp >=48 && temp <=57)|| temp == '('){
if(temp !='('){
S2.push(temp);
}else{
S1.push(temp);
provity = 0;
}
}else if(temp == ')'){
char ch;
while((ch = S1.pop())!='('){
S2.push(ch);
System.out.println(ch+"ddddd");
}
provity = getProvity(S1.peek());
System.out.println(provity+"ddddd");
}else if(S1.isEmpty() || S1.peek() == '(' || getProvity(temp) > getProvity(S1.peek())){
if(S1.isEmpty()) System.out.println("empty");
S1.push(temp);
provity = getProvity(temp);
System.out.println(temp);
}else{
while(getProvity(temp)<= getProvity(S1.peek())){
S2.push(S1.pop());
if(S1.isEmpty()){
break;
}
provity = getProvity(S1.peek());
}
S1.push(temp);
System.out.println(temp+"ssss");
provity = getProvity(S1.peek());
}
}
while(!S1.isEmpty()){
S2.push(S1.pop());
}
String rs=" ";
while(!S2.isEmpty()){
rs+=S2.pop();
}
return rs;
}
public static int getProvity(char ch){
switch(ch){
case '+':
case '-':
return 1;
case 'x':
case '/':
return 2;
}
return 0;
}
计算机计算后缀表达式
从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 op 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。
public static char getResult(String houzhui){
char result = ' ';
Stack<Character> S1 = new Stack<>();
int i ;
for(i = 0;i<houzhui.length();i++){
char temp = houzhui.charAt(i);
if(temp>=48&&temp <=57){
S1.push(temp);
System.out.println(temp+"aaaaaaaa");
}else{
char num2 = S1.pop();
char num1 = S1.pop();
char num3=' ';
int t;
switch(temp){
case '+':
t= num1-48+num2-48;
num3 = (char)(t +48);
break;
case '-':
t = num1-48-(num2-48);
num3 = (char)(t +48);
break;
case 'x':
t = (num1-48)*(num2-48);
num3 = (char)(t +48);
break;
case '/':
t = (num1-48)/(num2-48);
num3 = (char)(t +48);
break;
}
S1.push(num3);
System.out.println(num3-48);
}
}
result = S1.pop();
return result;
}
本篇参考于
http://blog.csdn.net/antineutrino/article/details/6763722/