好吧所以我有这个代码将中缀表达式转换为后缀表达式。有用!除了我希望它能够处理诸如“2 + * 5”或“wordswordswords”之类的错误。我该怎么做?谢谢!
package InToPostfix;
import java.io.IOException;
import javax.script.*;
/** Translates an infix expression to a postfix expression.
*
* @author Becky Hogan
*
*/
public class InToPost {
private Stack theStack;
private String input;
private String output = "";
public static void main(String[] args) throws Exception {
String input = "";
String output;
Object evaluated;
InToPost theTrans = new InToPost(input);
output = theTrans.evalOp();
InToPost result= new InToPost(input);
evaluated= result.evaluate(input);
System.out.println("Prefix is " + input + '\n');
System.out.println("Postfix is " + output + '\n');
System.out.println("The value:");
System.out.println(evaluated);
}
/** InToPost Method initiates the stack
*
* @param in the expression string
*/
public InToPost(String in) {
input = in;
int stackSize = input.length();
theStack = new Stack(stackSize);
}
/** evaluate Method evaluates the mathematical expression
*
* @param aString the expression string
* @return an object obj, the answer
* @throws Exception
*/
public Object evaluate(String aString) throws Exception {
// create a script engine manager
ScriptEngineManager factory = new ScriptEngineManager();
// create a JavaScript engine
ScriptEngine engine = factory.getEngineByName("JavaScript");
// evaluate JavaScript code from String
Object obj = engine.eval(aString);
return(obj);
}
/** evalOp Method decides what to do with the indexed character depending on if it is an operand or operator
*
* @return the postfix
* @throws Exception
*/
public String evalOp() throws Exception {
for (int j = 0; j < input.length(); j++) {
char ch = input.charAt(j);
switch (ch) {
case '+':
case '-':
processOperator(ch, 1);
break; // (precedence 1)
case '*': // it's * or /
case '/':
processOperator(ch, 2); // go pop operators
break; // (precedence 2)
case '(': // it's a left paren
theStack.push(ch); // push it
break;
case ')': // it's a right paren
gotParen(ch); // go pop operators
break;
default: // must be an operand
if(!Character.isJavaIdentifierPart(ch) && !Character.isDigit(ch)){
throw new Exception
("Unexpected Character Encountered");
}
output = output + ch; // write it to output
break;
}
}
while (!theStack.isEmpty()) {
output = output + theStack.pop();
}
return output; // return postfix
}
/** Method to determine the precedence of operators.
*
* @param opThis the character in the string
* @param prec1 precedence of previous operator
*/
public void processOperator(char opThis, int prec1) {
while (!theStack.isEmpty()) {
char opTop = theStack.pop();
if (opTop == '(') {
theStack.push(opTop);
break;
}// it's an operator
else {// precedence of new op
int prec2;
if (opTop == '+' || opTop == '-')
prec2 = 1;
else
prec2 = 2;
if (prec2 < prec1) // if prec of new op less
{ // than prec of old
theStack.push(opTop); // save newly-popped op
break;
} else
// prec of new not less
output = output + opTop; // than prec of old
}
}
theStack.push(opThis);
}
/** gotParen Method gets the previous operator
*
* @param ch the character in the string
*/
public void gotParen(char ch){
while (!theStack.isEmpty()) {
char chx = theStack.pop();
if (chx == '(')
break;
else
output = output + chx;
}
}
/**Stack class holds attributes for the stack needed for this assignment
*
* @author Becky Hogan
*
*/
class Stack {
private int maxSize;
private char[] stackArray;
private int top;
public Stack(int max) {
maxSize = max;
stackArray = new char[maxSize];
top = -1;
}
public void push(char j) {
stackArray[++top] = j;
}
public char pop() {
return stackArray[top--];
}
public char peek() {
return stackArray[top];
}
public boolean isEmpty() {
return (top == -1);
}
}
}
答案 0 :(得分:3)
这需要一个语法分析器规则。根据这种格式写一个:
EXPR: NUMBER OPERATOR NUMBER | NUMBER OPERATOR EXPR;
OPERATOR: '+' | '-'| '*' | '/';
NUMBER: [0-9]+
如果它与规则不匹配,那么它就是一个解析错误。
示例代码:(未测试):
class BadGrammarException extends Exception{
/**
*
*/
private static final long serialVersionUID = -2174692292489186639L;
}
class Validator{
public boolean isValid(String s)
{
if(s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")){
return true;
}else{
try{
Integer.parseInt(s);
}catch(Exception e){
return false;
}
}
return true;
}
}
class GrammarValidator{
private final int NUMBER = 0;
private final int OPERATOR = 1;
private int state = NUMBER;
public boolean isValidGrammatically(String line) throws BadGrammarException{
String[] tokens = line.split(" ");
boolean flag = true;
for(String p:tokens){
if(new Validator().isValid(p)){
/*everything is ok, token is valid*/
}else{
throw new BadGrammarException();
}
}
for(String p:tokens){
if(checkGrammar(p) == false){
flag = false;
}else{
}
}
return flag;
}
public boolean checkGrammar(String p) throws BadGrammarException{
if(state == NUMBER){
/*expecting integer*/
try{
Integer.parseInt(p);
}catch(Exception e){
throw new BadGrammarException();
}
state = OPERATOR;
return true;
}
if(state == OPERATOR){
/*expecting operator*/
if(p.equals("+") || p.equals("-") || p.equals("*") || p.equals("/")){
state = NUMBER;
return true;
}else{
throw new BadGrammarException();
}
}/*unknown state*/
return false;
}
}
我用以下代码测试了上面的代码:
public class Main{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
while(true){
System.out.println("CHECK >");
String line = scan.nextLine();
try{
if(new GrammarValidator().isValidGrammatically(line)){
System.out.println("Valid");
}
}catch(BadGrammarException be){
break;
}
}
}
}
看起来它在错误的输入上优雅地退出。你可以改变行为。输入验证后:您可以从中缀转换为后缀。
唯一需要注意的是,输入必须将NUMBERS和OPERATORS与单个(空格)分开 示例有效输入:10 + 20 + 30 + 40 + 50 - 30 - 20 示例INVALID输入:10 + 20 + 30 + 40 + 50-30-20
答案 1 :(得分:0)
您可以将潜在风险的代码包含在try-catch块中。
try {
InToPost theTrans = new InToPost(input);
output = theTrans.evalOp();
InToPost result= new InToPost(input);
evaluated= result.evaluate(input);
} catch (Exception e) {
System.out.println(e.getMessage());
}
例如,当发生逻辑错误时,您可以抛出异常。 就像你在这里所做的那样:
if(!Character.isJavaIdentifierPart(ch) && !Character.isDigit(ch)){
throw new Exception
("Unexpected Character Encountered");
}