2016-09-27 80 views
2

我想寫一個程序,將接收函數作爲字符串並解決它。例如。 「5 * 5 + 2/2-8 + 5 * 5-2」 應該返回41從字符串到整數函數

我寫了乘法和除法的代碼和它完美的作品:

public class Solver 
{ 
    public static void operationS(String m) 
    { 
     ArrayList<String> z = new ArrayList<String>(); 
     char e= ' '; 
     String x= " "; 
     for (int i =0; i<m.length();i++) 
     { 
      e= m.charAt(i); 
      x= Character.toString(e); 


      z.add(x); 
     } 
     for (int i =0; i<z.size();i++) 
      { 
       System.out.print(z.get(i)); 
      } 

     other(z); 
    } 

    public static void other(ArrayList<String> j) 
    { 
     int n1=0; 
     int n2=0; 
     int f=0; 
     String n= " "; 
      for (int m=0; m<j.size();m++) 
      { 

       if ((j.get(m)).equals("*")) 
       { 
       n1 = Integer.parseInt(j.get(m-1)); 
       n2 = Integer.parseInt(j.get(m+1)); 
       f= n1*n2; 
       n = Integer.toString(f); 

       j.set(m,n); 
       j.remove(m+1); 
       j.remove(m-1); 

       m=0; 
       } 

       for (int e=0; e<j.size();e++) 
       { 

        if ((j.get(e)).equals("/")) 
        { 
        n1 = Integer.parseInt(j.get(e-1)); 
        n2 = Integer.parseInt(j.get(e+1)); 
        f= n1/n2; 
        n = Integer.toString(f); 

        j.set(e,n); 
        j.remove(e+1); 
        j.remove(e-1); 

        e=0; 
        } 

       } 
    } 

      System.out.println(); 
      for (int i1 =0; i1<j.size();i1++) 
      { 
       System.out.print(j.get(i1)+","); 
      } 

但是,加法和減法,因爲心不是爲加減訂單,只是以先到者爲準,我寫了下面:

int x1=0; 
      int x2=0; 
      int x3=0; 
      String z = " "; 

      for (int g=0; g<j.size();g++) 
      { 
       if ((j.get(g)).equals("+")) 
       { 
        x1= Integer.parseInt(j.get(g-1)); 
        x2= Integer.parseInt(j.get(g+1)); 
        x3= x1+x2; 
        z = Integer.toString(x3); 

        j.set(g,z); 
        j.remove(g+1); 
        j.remove(g-1); 

        g=0; 
       } 
      g=0; 

       if ((j.get(g)).equals("-")) 
       { 
        x1= Integer.parseInt(j.get(g-1)); 
        x2= Integer.parseInt(j.get(g+1)); 
        x3= x1-x2; 
        z = Integer.toString(x3); 

        j.set(g,z); 
        j.remove(g+1); 
        j.remove(g-1); 

        g=0; 
       } 

       g=0; 
      } 

      System.out.println(); 
      for (int i1 =0; i1<j.size();i1++) 
      { 
       System.out.print(j.get(i1)+","); 
      } 

在此之後,它打印:

25 ,+,1, - ,8,+,25, - ,2,

。我究竟做錯了什麼?乘法和除法似乎是完美的工作

+0

的[評價以字符串形式表示數學表達式]可能的複製(http://stackoverflow.com/questions/3422673/evaluating-a-math-expression-given-in-string-form) – TiMr

回答

3

你有2個問題。

2)從你給的輸出,而第一負( - )是Unicode字符HYPHEN-MINUS (U+002D),而第二負( - )是Unicode字符EN DASH (U+2013),所以(j.get(g)).equals("-")失敗的第二負,因爲他們是不相等的。

+1

這就是這裏的好東西。總是有人也能識別「直接」問題。 – GhostCat

+0

我似乎不理解數字2.我如何解決在我的代碼?對不起,謝謝 – ZeldaX

+0

這不是關於代碼,而是輸入。第二個減號不是負數,它是一個短劃線,這是一個不同的字符。 – uoyilmaz

3

尋求一個答案,不能幫助你確切的具體問題,但希望可以幫助你遠遠超過這一點。

在乍看之下,存在着各種問題與您的代碼:

  1. 你正在使用所有的地方超級短變量名。這可以爲您節省1分鐘的打字時間;並且每次讀取代碼時花費5,10,x分鐘;或展示給其他人。所以:不這樣做。使用名稱來說明該名稱背後的內容。
  2. 您正在使用很多低級代碼。例如,您使用「couting-for」循環遍歷一個列表(稱爲j,這真的很可怕!)。含義:你使你的代碼比它應該更復雜。
  3. 這樣看來,目前爲止沒有人告訴你,但代碼的想法是:應該很容易閱讀和理解。可能你沒有取得成績,但相信我:從長遠來看,學習編寫可讀代碼是一項超級重要的技能。如果這讓你感到好奇,看看你是否能夠接觸Robert Martin的「Clean Code」。並研究那本書。然後再研究一遍。然後再次。

但真正的問題是你的方法來解決這個問題。正如我所假設的那樣:這是研究任務的一部分。下一步將是你沒有簡單的表達,如「1 + 2 * 3」;但是你被要求處理諸如「sqrt(2)+ 3」等等。然後你會被要求添加變量,等等。然後你的整個方法就會破裂。因爲你簡單的字符串操作不會再做。

在這個意義上說:你應該看看這個question,並仔細研究由Boann第二個答案,瞭解如何創建一個解析器是剖析你的輸入字符串轉換成表達然後被評估。你的代碼將兩個東西「結合在一起」。從而使提高所提供的功能變得非常困難。如果和其他塊會讓你以後進入無限循環

1)g=0;聲明:

+0

而你在'for'循環中設置'g = 0',我認爲這將是一個無限循環。 – Shadov

+0

@Whatzs我想你想「移動」你的評論而不是問題。我認爲你在這裏與錯誤的人「交談」;-) – GhostCat

+0

,因爲我希望它從頭開始檢查@Whatzs – ZeldaX

0

您可以使用內置的Javascript引擎

public static void main(String[] args) throws Exception{ 
    ScriptEngineManager mgr = new ScriptEngineManager(); 
    ScriptEngine engine = mgr.getEngineByName("JavaScript"); 
    String code = "5*5+2/2-8+5*5-2"; 
    System.out.println(engine.eval(code)); 
} 
+0

這是一個任務,我需要寫就像我在問題中顯示。謝謝@tionio – ZeldaX

0

主要不要重複自己(DRY原則)。並使用抽象(全稱,提取方法合理時)。使用多種方法時,靜態方法有點麻煩。這裏使用單獨的方法很方便。

也許你想是這樣的:

Solver solver = new Solver(); 
List<String> expr = solver.expression("5*5+2/2-8+5*5-2"); 
String result = solver.solve(expr); 

一個更抽象的求解器類會做:

class Solver { 

    List<String> expression(String expr) { 
     String[] args = expr.split("\\b"); 
     List<String> result = new ArrayList<>(); 
     Collections.addAll(result, args); 
     return result; 
    } 

    String solve(List<String> args) { 
     solveBinaryOps(args, "[*/]"); 
     solveBinaryOps(args, "[-+]"); 
     return args.stream().collect(Collectors.joining("")); 
    } 

以上solveBinaryOps以某種形式你想要的運營商接收到一個正則表達式模式或可替代簡單解決。 它照顧運營商的優先。

private void solveBinaryOps(List<String> args, String opPattern) { 
     for (int i = 1; i + 1 < args.length; ++i) { 
      if (args.get(i).matches(opPattern)) { 
       String value = evalBinaryOp(args.get(i - 1), args.get(i), args.get(i + 1)); 
       args.set(i, value); 
       args.remove(i + 1); 
       args.remove(i - 1); 
       --i; // Continue from here. 
      } 
     } 
    } 

    private String evalBinaryOp(String lhs, String op, String rhs) { 
     int x = Integer.parseInt(lhs); 
     int y = Integer.parseInt(rhs); 
     int z = 0; 
     switch (op) { 
     case "*": 
      z = x * y; 
      break; 
     case "/": 
      z = x/y; 
      break; 
     case "+": 
      z = x + y; 
      break; 
     case "-": 
      z = x - y; 
      break; 
     } 
     return Integer.toString(z); 
    } 
} 

以上幾點可以改進。但它是可讀的,可重寫的。

0
public class Solver { 
public static void main(String args[]) { 
    operation("5+2*5-6/2+1+5*12/3"); 
} 

public static void operation(String m) { 
    ArrayList<Object> expressions = new ArrayList<Object>(); 
    String e; 
    String x = ""; 
    for (int i = 0; i < m.length(); i++) { 
     e = m.substring(i, i + 1); 
     if (!(e.equals("*") || e.equals("/") || e.equals("+") || e 
       .equals("-"))) { 
      x += e; 
      continue; 
     } else { 
      if (!x.equals("") && x.matches("[0-9]+")) { 
       int oper = Integer.parseInt(x); 
       expressions.add(oper); 
       expressions.add(m.charAt(i)); 
       x = ""; 
      } 
     } 
    } 
    if (!x.equals("") && x.matches("[0-9]+")) { 
     int oper = Integer.parseInt(x); 
     expressions.add(oper); 
     x = ""; 
    } 
    for (int i = 0; i < expressions.size(); i++) { 
     System.out.println(expressions.get(i)); 
    } 
    evaluateExpression(expressions); 
} 

public static void evaluateExpression(ArrayList<Object> exp) { 
    //Considering priorities we calculate * and/first and put them in a list mulDivList 
    ArrayList<Object> mulDivList=new ArrayList<Object>(); 
    for (int i = 0; i < exp.size(); i++) { 
     if (exp.get(i) instanceof Character) { 
      if ((exp.get(i)).equals('*')) { 
       int tempRes = (int) exp.get(i - 1) * (int) exp.get(i + 1); 
       exp.set(i - 1, null); 
       exp.set(i, null); 
       exp.set(i + 1, tempRes); 
      } 
      else if ((exp.get(i)).equals('/')) { 
       int tempRes = (int) exp.get(i - 1)/(int) exp.get(i + 1); 
       exp.set(i - 1, null); 
       exp.set(i, null); 
       exp.set(i + 1, tempRes); 
      } 
     } 
    } 
    //Create new list with only + and - operations 

    for(int i=0;i<exp.size();i++) 
    { 
     if(exp.get(i)!=null) 
      mulDivList.add(exp.get(i)); 
    } 
    //Calculate + and - . 
    for(int i=0;i<mulDivList.size();i++) 
    { 
     if ((mulDivList.get(i)).equals('+')) { 
      int tempRes = (int) mulDivList.get(i - 1) + (int) mulDivList.get(i + 1); 
      mulDivList.set(i - 1, null); 
      mulDivList.set(i, null); 
      mulDivList.set(i + 1, tempRes); 
     } 
     else if ((mulDivList.get(i)).equals('-')) { 
      int tempRes = (int) mulDivList.get(i - 1) - (int) mulDivList.get(i + 1); 
      mulDivList.set(i - 1, null); 
      mulDivList.set(i, null); 
      mulDivList.set(i + 1, tempRes); 
     } 
    } 
    System.out.println("Result is : " + mulDivList.get(mulDivList.size() - 1)); 

} 
}