不评估双打

时间:2011-09-24 08:25:22

标签: java stack

好的,所以我发送双倍值并且不将它们解析为双精度而不是完全忽略小数值。这是我的代码,如果我输入2.0 + 5.0,它使它成为2 0 5 0 +。 =(

import java.beans.Expression;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Infix2Postfix {

private static String grabDigits(String s, int start){
    String num = "";
    for(int i=start; i < s.length(); i++){
        char ch = s.charAt(i);
        if(Character.isDigit(ch))
            num += ch;
        else
            return num;
    }

    return num;
}

private static Double apply(Double a, char op, Double b){
    switch(op){
    case '+' : return a + b;
    case '-' : return a - b;
    case '*' : return a * b;
    case '/' : return b == 0 ? null : a / b;
    default:
        return null;
    }
}
public static Double evalPostfix(String expr){
    Stack<Double> s = new Stack<Double>();


    for(int i=0; i<expr.length(); ){
        char ch = expr.charAt(i);

        if(Character.isDigit(ch)){
            String numStr = grabDigits(expr, i);
            i += numStr.length();
            Double value;

            if(isColmn(numStr)){
            value = getvaluefromcolmn(numStr);
            }else{
                value = Double.parseDouble(numStr);

            }
            s.push(value);
        }
        else {
            if(isOp(ch)){
                if(s.size() < 2) return null;
                Double b = s.pop();  // right arg
                Double a = s.pop();  // left arg
                s.push(apply(a, ch, b));
            }
            else if(!Character.isWhitespace(ch))
                return null;
            i++;  // consume individual char
        }
    }
    if(s.size() != 1) return null;
    return s.pop();
}

private static Double getvaluefromcolmn(String numStr) {
    // TODO Auto-generated method stub
    return null;
}

private static boolean isColmn(String numStr) {
    // TODO Auto-generated method stub
    return false;
}

private static int prec(char op){
    switch(op){
    case '+' :
    case '-' :
        return 0;
    case '*' :
    case '/' : 
        return 1;
    default:
        return -1;
    }
}
private static boolean isOp(char ch){
    return prec(ch) != -1;
}
public static String infix2postfix(String expr) {
    Stack<Character> s = new Stack<Character>();
    String pExpr = "";
    int numOperands = 0;
    int numOperators = 0;

    for(int i=0; i<expr.length(); i++){
        char ch = expr.charAt(i);
        if(Character.isDigit(ch)){
            pExpr += " " + ch;
            // could have used the grabDigits method here ...
            while(i+1 < expr.length() && Character.isDigit(expr.charAt(i+1))){
                pExpr += expr.charAt(i+1);
                i++;
            }
            numOperands++;
        }
        else if (ch == '(')
            s.push(ch);
        else if (ch == ')'){
            while(!s.empty() && s.peek() != '('){
                pExpr = pExpr + " " + s.pop() + " ";
                numOperators++;
            }
            if(s.empty())
                return "no matching open paren";
            if(numOperators >= numOperands)
                return "too many operators";
            s.pop();

        }
        else if(isOp(ch)){
            // pop operators with same or higher precedence
            while(!s.empty() && isOp(s.peek()) && prec(s.peek()) >= prec(ch)){
                pExpr = pExpr + " " + s.pop();
                numOperators++;
            }
            if(numOperators >= numOperands)
                return "too many operators";
            s.push(ch);
        }
        // else white space - do nothing

    }
    while(!s.empty()){
        char op = s.pop();
        if(!isOp(op))
            return "error";
        pExpr += " " + op;
    }
    return pExpr;

}

public static void exp(String expr, ArrayList<ArrayList<Comparable<?>>> entries){
    expr.replace("(", " ( ");
    expr.replace(")", " ) ");
    expr.replace("+", " + ");
    expr.replace(" - ", "  -  ");
    expr.replace("/", " /    ");
    expr.replace("*", " *   ");

    System.out.println("infix:   " + expr);
    System.out.println("this is at expreesion after replacing "+ expr);
    System.out.println("postfix: " + infix2postfix(expr));
    System.out.println("--------");
}
public static void main(String [] args){


    Scanner kbd = new Scanner(System.in);


    // ArrayList<int> tst;
    ArrayList<Integer> tst2;


    System.out.print("> ");
    while(kbd.hasNextLine()){
        String expr = kbd.nextLine();
         expr = expr.replaceAll("\\s+","");
        System.out.println(expr);
        Pattern pattern = Pattern.compile("\\s+");
          Matcher matcher = pattern.matcher(expr);
          boolean check = matcher.find();
          String str = matcher.replaceAll(" ");
    expr =  expr.replace("(", " ( ");

    expr =expr.replace(")", " ) ");
    expr =expr.replace("+", " + ");
    expr =expr.replace("-", " - ");
    expr =expr.replace("/", " / ");
    expr =expr.replace("*", " * ");
    String[] exprArray = expr.split(" ");



          System.out.println(str+ " this is expr "+exprArray[1]);
    System.out.println(expr);
        ArrayList<ArrayList<Comparable<?>>> entries = null;
        String pExpr = infix2postfix(expr);

        //System.out.println(evalPostfix(expr));

        System.out.println("  postfix version: " + pExpr);
        System.out.println("  eval(\"" + pExpr + "\"): " + evalPostfix(pExpr));
        System.out.print("> ");

    }


}

}

2 个答案:

答案 0 :(得分:4)

我没有详细检查您的代码,但是以下行

while(i+1 < expr.length() && Character.isDigit(expr.charAt(i+1))) ...

看起来你只解析数字但不解析每个表达式的'.'

您的方法grabDigits也是如此。

答案 1 :(得分:1)

通过停在第一个非数字位置,您将停在小数点,因此忽略它和它后面的所有内容。

请勿使用您自己的代码将字符串转换为双精度数,请使用Double.parseDouble()