【问题标题】:How to make an efficient expression calculator?如何制作一个高效的表达式计算器?
【发布时间】:2013-12-24 13:19:20
【问题描述】:

如何让代码读取用户输入的表达式中的多个操作数。

如果我必须阅读它们如何找到不同的运算符和操作数,这里是我制作的基本表达式计算器的代码,它能够读取表达式并仅计算一个操作数和两个运算符

例如 如果输入是 2+3 结果它会给我5.0
但是 如果输入是 2 + 3,即有空格,则它根本不提供任何输出,即使在有空格的情况下如何使其正常工作。

import java.util.Scanner;

public class Calc {

public static void main(String args[]){

    int j=0;

    float op1=0,op2=0,result=0;

    Scanner inp=new Scanner(System.in);

     System.out.println("Sir,Please enter the expression");

     String exp1=inp.next();

     String exp = exp1.replaceAll(" ","");

      for(int i=0;i<exp.length();i++){

         if(exp.charAt(i)=='+'||exp.charAt(i)=='-'||exp.charAt(i)=='*'||exp.charAt(i)=='/'){

           if(exp.charAt(i)=='+'){

                   i=j;

                   op1=Float.parseFloat(exp.substring(0, j+1));

                   op2=Float.parseFloat(exp.substring(j+2,exp.length()));

                   result=op1+op2;

                   System.out.println(result);

                   break;
             }

             if(exp.charAt(i)=='*'){

                   i=j;

                   op1=Float.parseFloat(exp.substring(0, j+1));

                   op2=Float.parseFloat(exp.substring(j+2,exp.length()));

                   result=op1*op2;

                   System.out.println(result);

                   break;

             }

             if(exp.charAt(i)=='-'){

                   i=j;

                   op1=Float.parseFloat(exp.substring(0, j+1));

                   op2=Float.parseFloat(exp.substring(j+2,exp.length()));

                   result=op1-op2;

                   System.out.println(result);

                   break;
             }

             if(exp.charAt(i)=='/'){

                   i=j;

                   op1=Float.parseFloat(exp.substring(0, j+1));

                   op2=Float.parseFloat(exp.substring(j+2,exp.length()));

                   if(op2==0){

                       System.err.println("Division by zero is not possible");

                       break;

                   }

                   else{

                      result=op1/op2;

                      System.out.println(result);

                      break; 
                   }

             }
         }


     }

}

}

【问题讨论】:

  • 你喜欢做一个计算器来计算像 2+3-5*2 这样的字符串吗?
  • 是的,我想做一个这样的计算器
  • 查看我对问题的回答
  • 请注意,new ScriptEngineManager().getEngineByName("JavaScript").eval("2+3-5*2"); 可以完成这项工作。

标签: java


【解决方案1】:

如果您希望对具有多个运算符和操作数的字符串执行计算,例如“2+3-5*4+2*sin(45)”,那么您需要研究如何将中缀解析为 RPN(反向波兰表示法) )

调车场算法就是这样一种通过高效解析完成复杂计算的方法。

我找不到太多与 java 相关的材料,因为我是一名 c# 开发人员。但是,我已经在我的一个 Windows Phone 项目中实现了相同的功能,并且可以正常工作。

目前我可以为您提供的链接很少。

Java Expression Parser & Calculator Shunting Yard Algorithm

http://en.wikipedia.org/wiki/Shunting-yard_algorithm

http://andreinc.net/2010/10/05/converting-infix-to-rpn-shunting-yard-algorithm/

有了这个,我在 c# 中附加了一些运算符及其优先级规则 查看我上面提到的堆栈溢出链接,然后研究我在下面写的内容。

            OPERATORS.Add("+", new int[] { 0, LEFT_ASSOC });
            OPERATORS.Add("-", new int[] { 0, LEFT_ASSOC });
            OPERATORS.Add("*", new int[] { 5, LEFT_ASSOC });
            OPERATORS.Add("/", new int[] { 5, LEFT_ASSOC });
            OPERATORS.Add("%", new int[] { 5, LEFT_ASSOC });
            OPERATORS.Add("^", new int[] { 10, RIGHT_ASSOC });
            OPERATORS.Add("Sin", new int[] { 10, RIGHT_ASSOC });
            OPERATORS.Add("Cosh", new int[] { 10, RIGHT_ASSOC });
            OPERATORS.Add("Sinh", new int[] { 10, RIGHT_ASSOC });
            OPERATORS.Add("Tanh", new int[] { 10, RIGHT_ASSOC });
            OPERATORS.Add("Cos", new int[] { 10, RIGHT_ASSOC });
            OPERATORS.Add("Tan", new int[] { 10, RIGHT_ASSOC });
            OPERATORS.Add("Log", new int[] { 10, RIGHT_ASSOC });
            OPERATORS.Add("ln", new int[] { 10, RIGHT_ASSOC });
            OPERATORS.Add("Sqrt", new int[] { 10, RIGHT_ASSOC });
            OPERATORS.Add("Floor", new int[] { 10, RIGHT_ASSOC });
            OPERATORS.Add("Ceil", new int[] { 10, RIGHT_ASSOC });
            OPERATORS.Add("Square", new int[] { 10, RIGHT_ASSOC });

【讨论】:

  • 先生,我对c#一无所知,请您帮我解决一些java问题。
  • 我在答案中添加了一个链接来帮助你检查它(我希望它有帮助)!只有我能坐在这里。您需要自己实现该算法。我在 c# 中使用相同的算法实现为 windows phone 制作了一个计算器,请查看此链接-windowsphone.com/en-us/store/app/make-maths-easy/…
  • 一切顺利,该方法确实有效,抱歉,我不能让我的手更脏。
【解决方案2】:

如果您只想阻止空格干扰您的评估,只需删除它们:

示例

String expression = "2 + 2";
String parsedExpression = expression.replaceAll(" ", "");

// Evaluate.

为了学究而编辑

Scanner s = new Scanner(System.in);
System.out.print("Enter an expression and hit enter: "); 
String expression = s.readLine();

String parsedExpression = expression.replaceAll(" ", "");

【讨论】:

  • 这段代码会删除用户输入的字符串之间的空格吗?
  • 它不工作它在执行时根本没有输出
  • 这会将2 + 2 转换为2+2。这是一个工作示例:ideone.com/dl5u3D
  • @Chris 您提供的解决方案非常适合这种情况,但是当要计算的表达式发生变化时会发生什么?
  • 这只是一个例子.. 显然这是一个非常简单的步骤,允许用户更改输入..
【解决方案3】:

嘿,克里斯,理想情况下它现在应该可以工作,但现在仍然无法工作,你能告诉我该怎么做吗?我已经修改了 replacAll 语句,你可以检查一下吗?

导入 java.util.Scanner;

公共类计算{

public static void main(String args[]){

int j=0;

float op1=0,op2=0,result=0;

Scanner inp=new Scanner(System.in);

 System.out.println("Sir,Please enter the expression");

 String exp1=inp.next();

 String exp = exp1.replaceAll("\\s","");    //It will replace all the spaces from the string

  for(int i=0;i<exp.length();i++){

     if(exp.charAt(i)=='+'||exp.charAt(i)=='-'||exp.charAt(i)=='*'||exp.charAt(i)=='/'){

       if(exp.charAt(i)=='+'){

               i=j;

               op1=Float.parseFloat(exp.substring(0, j+1));

               op2=Float.parseFloat(exp.substring(j+2,exp.length()));

               result=op1+op2;

               System.out.println(result);

               break;
         }

         if(exp.charAt(i)=='*'){

               i=j;

               op1=Float.parseFloat(exp.substring(0, j+1));

               op2=Float.parseFloat(exp.substring(j+2,exp.length()));

               result=op1*op2;

               System.out.println(result);

               break;

         }

         if(exp.charAt(i)=='-'){

               i=j;

               op1=Float.parseFloat(exp.substring(0, j+1));

               op2=Float.parseFloat(exp.substring(j+2,exp.length()));

               result=op1-op2;

               System.out.println(result);

               break;
         }

         if(exp.charAt(i)=='/'){

               i=j;

               op1=Float.parseFloat(exp.substring(0, j+1));

               op2=Float.parseFloat(exp.substring(j+2,exp.length()));

               if(op2==0){

                   System.err.println("Division by zero is not possible");

                   break;

               }

               else{

                  result=op1/op2;

                  System.out.println(result);

                  break; 
               }

         }
     }


 }

}

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-04
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多