如何解决后缀运算符与 convertInfixToPostfix Java 类无序
所以我用 Java 编写了一个有效的 infixToPostifxConverter 类,它正确地转换了以下表达式: 中缀:6 + 2 * 5 -8 / 4 正确的后缀:6 2 5 * + 8 4 / - 中缀:6 % 2 ^ 5 -8 / 4 * 5 正确的后缀:6 2 5 ^% 8 4 / 5* -
但我已经使用 switch 语句实现了优先级方法,根据传递给它的运算符类型返回 1、2 或 3。如果operator1 的优先级低于operator2,我实际上需要编写返回true 的方法。否则,它应该返回 false。
但是当我重构以返回 true 或 false 时,我的后缀表达式不再正确并且以错误的顺序返回操作数。查看我在 convertToPostfix 方法中标记“我认为问题在这里”的位置。我无法弄清楚我做错了什么?任何见解将不胜感激!
导入 java.util.Scanner; 公共类 InfixToPostfixConverter {
public Stack<Character> stack = new Stack<>();
public static void main(String[] args) { // main method
InfixToPostfixConverter obj = new InfixToPostfixConverter(); // class object
int cont = 0; // create variable to control pre-test loop
Scanner sc = new Scanner(system.in); // create object to capture input
while (cont != -1) {
System.out.println("Enter expression to convert (no spaces!): ");
//get user input infix expression
StringBuffer infix = new StringBuffer();
infix.append(sc.next());
//output user input as postfix expression
System.out.println("Postfix expression is:" + obj.convertToPostfix(infix));
System.out.println("Enter -1 to quit. Else enter any single digit number to continue: ");
cont = sc.nextInt(); // continue looping until user exits program
};
}
//***************************************************************
//
// Method: convertToPostfix() method
//
// Description: takes the infix StringBuffer expression as input
// and returns converted postfix expression as result
//
// Parameters: StringBuffer infix
//
// Returns: StringBuffer postfix
//**************************************************************
public StringBuffer convertToPostfix(StringBuffer infix) {
StringBuffer postfix = new StringBuffer(""); // variable to store converted postfix expression
InfixToPostfixConverter obj = new InfixToPostfixConverter(); // class object
for (int i = 0; i < infix.length(); i++) { // while there is input to read
char c = infix.charat(i);
// if scanned character is operand...
if (Character.isLetterOrDigit(c))
postfix.append(c); // ...add to output
// if scanned character is '('...
else if (c == '(')
stack.push(c); // ...push onto stack
else if (c == ')')
// push all input back to (
{
while (!stack.isEmpty() && stack.peek() != '(') {
postfix.append(stack.pop()); // add to output
}
stack.pop(); // remove '('
}
else // print operators occurring before which have a higher precedence
{
while (!stack.isEmpty() && obj.isOperator(c) && **obj.precedence(c,stack.peek()))** // I THINK PROBLEM IS HERE
{
postfix.append(stack.pop()); // add to output
}
stack.push(c); // push onto stack
}
}
while (!(stack.isEmpty())) // stack is not empty...
{
postfix.append(stack.pop()); // ...add to output
}
return postfix;
}
//***************************************************************
//
// Method: precedence() method
//
// Description: determines whether
// the precedence of operator1 (from the infix expression)
// is less than,equal to or greater than,// that of operator2 (from the stack)
//
// Parameters: char x
//
// Returns: true if operator1 has a precedence lower than that of operator2
// else,returns false
//**************************************************************
public boolean precedence(char operator1,char operator2)
{
int op1Precedence = 0;
int op2Precedence = 0;
//assign operator1 precedence an integer value from 1-3
if(operator1 == '+' || operator1 == '-')
op1Precedence = 1;
else if(operator1 == '*' || operator1 == '/' || operator1 == '%')
op1Precedence = 2;
else if(operator1 == '^')
op1Precedence = 3;
//assign operator2 precedence an integer value from 1-3
if(operator2 == '+' || operator2 == '-')
op2Precedence = 1;
else if(operator2 == '*' || operator2 == '/' || operator2 == '%')
op2Precedence = 2;
else if(operator2 == '^')
op2Precedence = 3;
//compare precedence of operator1 and operator2
if(op1Precedence < op2Precedence)
return true;
else
return false;
}
//***************************************************************
//
// Method: isOperator() method
//
// Description: determines if c is an operator
//
// Parameters: char c
//
// Returns: true if c is an operator
// else,returns false
//**************************************************************
public boolean isOperator(char c)
{
// if c is operator...
if( c == '+' || c == '-' || c == '*' || c == '/' || c == '^' || c == '%')
return true; // return true
else
return false;
}
}
解决方法
试试这个。
static final Map<Integer,Integer> PRIORITY = Map.of(
(int)'+',1,(int)'-',(int)'*',2,(int)'/',(int)'%',(int)'^',3);
static String convertToPostfix(String infix) {
StringBuilder postfix = new StringBuilder();
new Object() {
int index = 0;
int ch = get();
int token;
int get() { return ch = index < infix.length() ? infix.charAt(index++) : -1; }
void put(int... chars) { for (int c : chars) postfix.append((char)c); }
void spaces() { while (Character.isWhitespace(ch)) get(); }
boolean match(int... expects) {
spaces();
for (int e : expects)
if (ch == e) {
token = ch;
get();
return true;
}
return false;
}
void number() {
if (ch == '-') {
put(ch); get();
if (!Character.isDigit(ch))
throw new RuntimeException("digits expected");
}
do {
put(ch); get();
} while (Character.isDigit(ch));
}
void factor() {
if (match('(')) {
expression();
if (!match(')'))
throw new RuntimeException("')' expected");
} else if (ch == '-' || Character.isDigit(ch))
number();
else
throw new RuntimeException("unknown char '" + (char) ch + "'");
}
void expression() {
Deque<Integer> stack = new LinkedList<>();
factor();
while (match('+','-','*','/','%','^')) {
int op = token;
int p = PRIORITY.get(op);
while (!stack.isEmpty() && p <= PRIORITY.get(stack.peek()))
put(' ',stack.pop());
stack.push(op);
put(' ');
factor();
}
while (!stack.isEmpty())
put(' ',stack.pop());
}
}.expression();
return postfix.toString();
}
和
System.out.println(convertToPostfix("6 + 2 * 5 - 8 / 4"));
System.out.println(convertToPostfix("6 % 2 ^ 5 - 8 / 4 * 5"));
System.out.println(convertToPostfix("654 + 21 * (54 - 87) / 4"));
输出:
6 2 5 * + 8 4 / -
6 2 5 ^ % 8 4 / 5 * -
654 21 54 87 - * 4 / +
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。