2011-09-24 56 views
2

好吧,所以我发送双打价值这个,它不解析他们作为双打,而是完全忽略了十进制值。这里是我的代码,如果我输入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("> "); 

    } 


} 

}

+0

另请考虑['StreamTokenizer'](http://download.oracle.com/javase/7/docs/api/java/io/StreamTokenizer.html)。 – trashgod

+1

哦对不起,我不知道我可以做到这一点:) –

+0

这闻起来像一个家庭作业。 – TJR

回答

4

我没有详细检查你的代码,但是下面一行

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

看起来像你只解析数字而不是'.'每个表达式。

这同样适用于您的方法grabDigits

+0

但我不想按数字去? –

+0

@ashleysmith你是对的,但数字(至少双打)也可能包含非数字,你必须考虑到。 – Howard

+0

哦,是啊,我忘了。我应该只做expr.charAt(i + 1)!='+'|| expr.charAt(i + 1)!=' - '像那样比? –

1

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

不要将字符串转换为您自己的代码加倍,请使用Double.parseDouble()

+0

我想使用,但infix2postfix方法设置它的方式不让我。真的坚持如何设置它,所以我可以使用double.parse –

+0

如果我设置double.parseDouble我可以使用它来加减负数:D –

+0

@ashley smith'infix2postfix方法设置其方式不让我':这是不可能相信的。 – EJP