题目要求:完成Java程序设计
要求:实现中缀表达式到后缀表达式的转换,为InfixToPostfix类实现convertExpr(String expression),其中参数expression为中缀表达式,其返回值为后缀表达式,最后将其输出到控制台即可。
对输入进来的字符串依次扫描每一个字符,将其按:数字、括号和运算符(加、减、乘、除)分类,不同类别的字符按不同的方法处理。
数字:直接添加进后缀表达式的字符串;
括号:左括号直接入栈,表示进入一个新的计算层次。右括号无需入栈,只为匹配栈中的左括号,所以要将左括号之前的运算符依次出栈并添加到后缀表达式的字符串,直到匹配到左括号,出栈。
运算符:乘除号的优先级高于加减号,所以直接入栈。加减号的优先级低,且后面的加减号优先级低于之前的,所以如果有加减号要入栈,先必须将栈中其他优先级高的运算符出栈并添加到后缀表达式的字符串,直到栈空或栈顶是左括号,再将其入栈;
测例:
① 输入:(1+2)*(9-8)#
输出:12+98-*
② 输入:1+2-3+4-5#
输出:12+3-4+5-
③ 输入:1+(2-3)+4-5#
输出:123-+4+5-
④ 输入:1*3%4#
输出:输入格式错误!!!
要求:实现中缀表达式到后缀表达式的转换,为InfixToPostfix类实现convertExpr(String expression),其中参数expression为中缀表达式,其返回值为后缀表达式,最后将其输出到控制台即可。
中缀表达式符合人们平时的表达习惯,如:(1+2)*(9-5)。但是计算机在计算这样的表达式时却不会像我们人类一样的思维,而是用逆波兰表达式,是一种不需要括号的后缀表达式。刚刚的表达式的后缀表达式为:12+95-*。
对输入进来的字符串依次扫描每一个字符,将其按:数字、括号和运算符(加、减、乘、除)分类,不同类别的字符按不同的方法处理。
数字:直接添加进后缀表达式的字符串;
括号:左括号直接入栈,表示进入一个新的计算层次。右括号无需入栈,只为匹配栈中的左括号,所以要将左括号之前的运算符依次出栈并添加到后缀表达式的字符串,直到匹配到左括号,出栈。
运算符:乘除号的优先级高于加减号,所以直接入栈。加减号的优先级低,且后面的加减号优先级低于之前的,所以如果有加减号要入栈,先必须将栈中其他优先级高的运算符出栈并添加到后缀表达式的字符串,直到栈空或栈顶是左括号,再将其入栈;
Java代码如下:
import java.util.Stack;
import java.util.Scanner;
public class InfixToPostfix
{
private String converExpr( String expression )
{
//中缀表达式为传入参数,是字符串形式,用InfixIndex来遍历
//后缀表达式为字符串数组result,用PostfixIndex来遍历,最后将其变为字符串返回
int InfixIndex = 0, PostfixIndex = 0;
Stack<Character> stack = new Stack<Character>();
char result[] = new char[100];
char topChar, curChar; //topChar:栈顶运算符, curChar:中缀表达式当前字符
while( expression.charAt(InfixIndex) != '#' )
{
curChar = expression.charAt(InfixIndex);
//若是数字,直接添加进字符数组
if( curChar >= '0' && curChar <= '9' )
{
result[PostfixIndex] = curChar;
PostfixIndex++;
}
//若是右括号,则将栈中其他运算符出栈,添加进字符数组,直到匹配到左括号,将其出栈
else if( curChar == ')' )
{
while( stack.peek() != '(' )
{
result[PostfixIndex] = stack.peek();
PostfixIndex++;
stack.pop();
}
stack.pop(); //弹出左括号
}
//若是加减号,其优先级最低,低于之前入栈的加减号(优先级从左到右),
//将之前的运算符出栈,添加进字符数组,直到栈空或左括号,最后将加减号入栈
else if( curChar == '+' || curChar == '-' )
{
if( stack.isEmpty() ) //空栈就直接入栈
{
stack.push( curChar );
}
else //弹出优先级高于加减号的运算符
{
while( !stack.isEmpty() )
{
topChar = stack.peek();
stack.pop();
if( topChar == '(' )
{
stack.push( topChar );
break;
}
else
{
result[PostfixIndex] = topChar;
PostfixIndex++;
}
}
stack.push(curChar);
}
}
//若是乘除或左括号,优先级高,直接入栈
else if( curChar == '*' || curChar == '/' || curChar == '(' )
{
stack.push( curChar );
}
//其他情况表明输入错误
else
{
return "输入格式错误!!!";
}
InfixIndex++;//所有情况比较完后考虑输入参数字符串的下一字符
}
//所有字符串遍历完之后将栈中剩余运算符出栈
while( !stack.isEmpty() )
{
result[PostfixIndex] = stack.peek();
PostfixIndex++;
stack.pop();
}
//将字符数组转为字符串,返回
String ee = new String(result);
return ee;
}
public static void main(String[] args)
{
InfixToPostfix str = new InfixToPostfix();
System.out.print("————中缀表达式转后缀表达式————\n");
System.out.print("请输入一个中缀表达式的字符串:(输入#结束)\n");
Scanner in = new Scanner(System.in);
String inFix = in.next();//inFix:中缀表达式的字符串
String postFix = new String(); //postFix:后缀表达式的字符串
postFix = str.converExpr(inFix);
System.out.print("其后缀表达式为:\n");
System.out.print(postFix);
in.close();
}
}
测例:
① 输入:(1+2)*(9-8)#
输出:12+98-*
② 输入:1+2-3+4-5#
输出:12+3-4+5-
③ 输入:1+(2-3)+4-5#
输出:123-+4+5-
④ 输入:1*3%4#
输出:输入格式错误!!!
评价:
程序实现的功能较为简单,其中对表达式的要求也较高,比如:输入的数字必须为正整数,不能是小数和负数。括号必须是小括号。
此外,若输入的中缀表达式为:111+11*6#,输出的结果为:111116*+,难以区分数字。