Java 字符串计算器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25130788/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 23:41:42  来源:igfitidea点击:

Java String Calculator

java

提问by tmax

I'm trying to make a simple calculator in Java which takes input in the form of a string and does a simple '+' and '-' operation.

我正在尝试用 Java 制作一个简单的计算器,它以字符串的形式输入并执行简单的“+”和“-”操作。

Single digit inputs work but my problem is when i try to implement this for double digit

一位数输入有效,但我的问题是当我尝试为两位数实现这个时

input string is: 5+20+5+11
list 1 = [5, 20, 2, 0, 5, 11, 1]
list 2 = [+, +, +]
Answer:27

输入字符串为:5+20+5+11
list 1 = [5, 20, 2, 0, 5, 11, 1]
list 2 = [+, +, +]
答案:27

I need to find a way where after storing [5] in list1 how i can add [5,20] instead of [5,20,2,0] which the current code is doing.

我需要找到一种方法,在将 [5] 存储在 list1 中之后,我如何添加 [5,20] 而不是当前代码正在执行的 [5,20,2,0] 。

public int calC(String input) {
        int len = input.length();
        ArrayList list1 = new ArrayList();
        ArrayList list2 = new ArrayList();
        for (int i = 0; i < len; i++) {
            if ((input.charAt(i) != '+') && (input.charAt(i) != '-')) {
                // check if the number is double-digit
                if ((i + 1 <= len - 1)) {
                    if ((input.charAt(i + 1) != '+')&& (input.charAt(i + 1) != '-')) {
                        String temp = "";
                        temp = temp + input.charAt(i) + input.charAt(i + 1);
                        int tempToInt = Integer.parseInt(temp);
                        // adding the double digit number
                        list1.add(tempToInt);
                    }
                    // add single digit number
                    list1.add(input.charAt(i) - '0');
                }
            } else {
                // adding the symbols
                list2.add(input.charAt(i));
            }
        }
        int result = 0;
        result = result + (int) list1.get(0);
        for (int t = 0; t < list2.size(); t++) {
            char oper = (char) list2.get(t);
            if (oper == '+') {
                result = result + (int) list1.get(t + 1);

            } else if (oper == '-') {
                result = result - (int) list1.get(t + 1);
            }
        }
        return result;
    }

Edit: working version
@Ker p pag thanks for the updated methods
input string is: 5+20+5+11
[5, 20, 5, 11]
[+, +, +]
Answer:41
I'll need to try to implement this with stack as suggested but the current version works

编辑:工作版本
@Ker p pag 感谢更新方法
输入字符串是:5+20+5+11
[5, 20, 5, 11]
[+, +, +]
答案:41
我需要尝试按照建议使用堆栈实现此功能,但当前版本有效

static boolean isDigit(char check) {
    if (Character.isDigit(check)) {
        return true;
    }
    return false;
}
public static int calC(String input) {

    int len = input.length();
    ArrayList list1 = new ArrayList();
    ArrayList list2 = new ArrayList();

    for (int i = 0; i < len; i++) {
        if ((i + 1 <= len - 1)) {
            if (isDigit(input.charAt(i)) && isDigit(input.charAt(i + 1))) {
                String temp = input.charAt(i) + "" + input.charAt(i + 1);
                int toInt = Integer.parseInt(temp);
                list1.add(toInt);
                i = i+1;
            } else if (isDigit(input.charAt(i))) {
                list1.add(input.charAt(i)- '0');
            } else {
                list2.add(input.charAt(i));
            }

        }
    }

    int result = 0;
    result = result + (int) list1.get(0);
    for (int t = 0; t < list2.size(); t++) {
        char oper = (char) list2.get(t);
        if (oper == '+') {
            result = result + (int) list1.get(t + 1);

        } else if (oper == '-') {
            result = result - (int) list1.get(t + 1);
        }
    }
    return result;
}

回答by Ker p pag

for storing the input to the list you could try this snippet

要将输入存储到列表中,您可以尝试此代码段

for (int i = 0; i < input.length() - 1; i++) {

        // make a method
        // check if current character is number || check if current
        // character is number and the next character
        if (isDigit(input.charAt(i)) && isDigit(input.charAt(i + 1))) {

            list.add(input.charAt(i) +""+ input.charAt(i + 1));

        } else if (isDigit(input.charAt(i))) {

            list.add(input.charAt(i));

        }else{
            operator.add(input.charAt(i));
        }

    }


//check if it is a number
public boolean isDigit(char input){
if(input == '1' ||
input == '2' ||
input == '3' ||
input == '4' ||
input == '5' ||
input == '6' ||
input == '7' ||
input == '8' ||
input == '9' ||
input == '0')
    return true;

    return false;
}

回答by Wundwin Born

If you want the result 41for input string "5+20+5+11", why not use ScriptEngineManagerwith JavaScriptengine,

如果您想要41输入 string的结果"5+20+5+11",为什么不ScriptEngineManagerJavaScript引擎一起使用,

public double calC(String input) {
    int result = 0;
    ScriptEngineManager mgr = new ScriptEngineManager();    
    ScriptEngine engine = mgr.getEngineByName("JavaScript");        
    return (Double)engine.eval(input);
}

But note that the return type is doublehere.

但请注意,返回类型在double这里。

If you want only intas return type in this case, try with this

如果你只想要int在这种情况下作为返回类型,试试这个

return new BigDecimal(engine.eval(input).toString()).intValue();

回答by Puneet_Techie

I agree that stack is the best solution,but still giving an alternative way of doing this.

我同意堆栈是最好的解决方案,但仍然提供了一种替代方法。

   String input = "5+20+11+1";
   StringBuilder sb = new StringBuilder();
   List<Integer> list1 = new ArrayList<Integer>();
   List<Character> list2 = new ArrayList<Character>();
   char[] ch = input.toCharArray();
   for(int i=0;i<ch.length;i++)
   {
       if(ch[i]!='+')
       { 

           sb.append(ch[i]);
       }else
       {

           list2.add(ch[i]);
           list1.add(Integer.valueOf(sb.toString()));
           sb.setLength(0); 
       }
   }
   if(sb.length()!=0)
       list1.add(Integer.valueOf(sb.toString()));
   System.out.println(list1.size());
   for(Integer i:list1)
   {
       System.out.println("values"+i);
   }

回答by AlexanderBrevig

Another way to think about this:

另一种思考方式:

public class InlineParsing {
    public static void main(String []args){
        String input = "5-2+20+5+11-10";
        input = input.replace(" ","");

        String parsedInteger = "";
        String operator = "";
        int aggregate = 0;
        for (int i = 0; i < input.length(); i++){
            char c = input.charAt(i); 
            if (Character.isDigit(c)) {
                parsedInteger += c;
            }
            if (!Character.isDigit(c) || i == input.length()-1){
                int parsed = Integer.parseInt(parsedInteger);
                if (operator == "") {
                    aggregate = parsed;
                }
                else {
                    if (operator.equals("+")) {
                        aggregate += parsed;
                    }else if (operator.equals("-")){
                        aggregate -= parsed;
                    }
                }

                parsedInteger ="";
                operator = ""+c;
            }
        }
        System.out.println("Sum of " + input+":\r\n" + aggregate);
    }
}

It's basically a state machine that traverses over each char.

它基本上是一个遍历每个字符的状态机。

Iterate over each char:

迭代每个字符:

  1. if current char is a digit, add to current number buffer
  2. if current char is not a digit or we're parsing the last digit
    1. if an operator has been parsed use that to add the newly parsed number to the sum if no operator has been parsed, set sum to current parsed number
    2. clear current number buffer
    3. store current char as operator
  1. 如果当前字符是数字,则添加到当前数字缓冲区
  2. 如果当前字符不是数字或者我们正在解析最后一位数字
    1. 如果已经解析了运算符,则使用该运算符将新解析的数字添加到总和中,如果未解析任何运算符,则将总和设置为当前已解析的数字
    2. 清除当前号码缓冲区
    3. 将当前字符存储为运算符

回答by HJK

Here is the code:

这是代码:

    String a = "5+20-15+8";
    System.out.println(a);
    String operators[]=a.split("[0-9]+");
    String operands[]=a.split("[+-]");
    int agregate = Integer.parseInt(operands[0]);
    for(int i=1;i<operands.length;i++){
        if(operators[i].equals("+"))
            agregate += Integer.parseInt(operands[i]);
        else 
            agregate -= Integer.parseInt(operands[i]);
    }
    System.out.println(agregate);

回答by chAlexey

I could advise you to use Exp4j. It is easy to understand as you can see from the following example code:

我可以建议您使用Exp4j。从以下示例代码中可以看出,它很容易理解:

Expression e = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
    .variables("x", "y")
    .build()
    .setVariable("x", 2.3)
    .setVariable("y", 3.14);
double result = e.evaluate();

Especially for the case of using more complex expression this could be a better choice.

特别是对于使用更复杂表达式的情况,这可能是更好的选择。

回答by Abhishek Singh

private static int myCal() {
 String[] digits = {
  "1",
  "2",
  "3",
  "4",
  "5"
 };
 String[] ops = {
  "+",
  "+",
  "+",
  "-"
 };
 int temp = 0;
 int res = 0;
 int count = ops.length;

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

  res = Integer.parseInt(digits[i]);
  if (i != 0 && count != 0) {
   count--;
   switch (ops[i - 1]) {
    case "+":
     temp = Math.addExact(temp, res);
     break;

    case "-":
     temp = Math.subtractExact(temp, res);
     break;
    case "*":
     temp = Math.multiplyExact(temp, res);
     break;
    case "/":
     temp = Math.floorDiv(temp, res);
     break;
   }
  }
 }
 return temp;
}