2016-09-27 87 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)); 

} 
}