计算Java中的负数

时间:2014-10-27 15:55:48

标签: java calculator

好的......我想绕过计算负数的概念。我在自学,我遇到了很多困难。如何实施负面输入?

我的代码:

public class MainSystem {

    public static void main(String[] args) {
        try (Scanner console = new Scanner(System.in)) {
            String input;

            System.out.print(">>> ");
            input = console.nextLine();
            splitEntry(input);

            System.out.println("The console is now closed.");
        }
    }

    private static void splitEntry(String input) {

        String function = "[+\\-*/]+"; //placing them in an index
        String[] token = input.split(function);//and this
        double num1 = Double.parseDouble(token[0]);
        double num2 = Double.parseDouble(token[1]);
        //double answer;
        String operator = input.toCharArray()[token[0].length()] + "";

        if (operator.matches(function) && (token[0] + token[1] + operator).length() == input.length()) {
            System.out.println("Operation is " + operator + ", your first number is " + token[0] + " your second number is " + token[1]);
        } else {
            System.out.println("Your entry of " + input + " is invalid");
        }
        if (operator.matches(function)
                && (token[0] + token[1] + operator).length() == input.length()) {
            double result = 0;
            if (operator.equals("+")) { // this is simplified by using formatters 
                result = num1 + num2;
            } else if (operator.equals("-")) {
                result = num1 - num2;
            } else if (operator.equals("*")) {
                result = num1 * num2;
            } else if (operator.equals("/")) {
                result = num1 / num2;
            }
            System.out.printf("Your first number %.2f %s by your second number %.2f = makes for %.2f%n", num1, operator, num2,
                    result);
        }
    }
}

如何让我的计算器放置-2 + 5并得到答案3?

每当我尝试这样做时,程序崩溃了?如何计算负数

1 个答案:

答案 0 :(得分:1)

好的,我想我有事。对不起,迟到的答案,我希望你仍然可以使用它。 首先让我解释一下,我改变了很多代码。

扫描输入
输入将作为一个完整的String读取,就像在代码中一样。但是,不是将代码拆分为String[],而是逐个“检查”字符,并尝试确定它们是运算符还是数字。

如果我找到一个数字或一个运算符,我把它放在一个列表而不是数组中,因为列表可以动态增长,但我不知道有多少数字和运算符。

private static ArrayList<String> getSequence(String input) {
    String number = "[\\d,.]+";     // RegEx to detect any number 12 or 1.2 or 1,2
    String function = "[+\\-*/]+";  // RegEx to detect any operator +-*/ 
    char[] inputChars = input.toCharArray();   // converting the input String into an array
    ArrayList<String> sequence = new ArrayList<>();  // this is the list, that will be returned
    String lastNumber = "";     // a number can consist of multiple chars, so this String is like a buffer for us where we "collect" every char until the number is complete

    for (char c : inputChars) {  // now we loop through every char in the char[]
        System.out.println("checking " + c);
        if ((new String("" + c)).matches(function)) {  // we convert our char into a String and try to match it with the "function" RegEx
            System.out.println("its an operator");
            if (!lastNumber.isEmpty()) {
                sequence.add(lastNumber); // if we detect an operator, we must check if we still have a number in our buffer. So we add the last number to our list
            }
            sequence.add("" + c);  // and we add our operator to our list
            lastNumber = "";       // we just saw an operator, so the "lastNumber" buffer should be cleared
        } else if ((new String("" + c)).matches(number)) {  // if we detect a digit/number
            System.out.println("its part of a number");
            lastNumber += c; // since this char is part of a number, we add it to the "lastNumber" buffer
            // now we need to continue, since we don't know if the number is already finished 
        }
    }
    // if we finished analyzing the char array, there might be a last number in our buffer
    if (!lastNumber.isEmpty()) {  
        sequence.add(lastNumber);  // the last number will be added too
    }
    return sequence;  // now our sequence is complete and we return it
}

因此,当我们的输入类似于1+2+3时,此方法将返回此列表:

{"1", "+", "2", "+", "3"}

评估序列
接下来,我们调用方法evaluate(sequence)来评估我们的列表。这非常接近你的方式,我只做了一些调整

 private static void evaluate(ArrayList<String> sequence) {
    double number1 = 0.0;    // the first number is also a intermediary result
    while (true) {           // we actually don't know how long the equation is, so here we have an infinite-loop. Usually not a good idea!
        try {                // we try to evaluate the next String of our sequence
            number1 = getNextNumber(sequence);  // get the next number 
            System.out.println("number1 = " + number1);
            char operator = getNextOperator(sequence);  // get the next operator
            System.out.println("operator = " + operator);
            double number2 = getNextNumber(sequence);
            System.out.println("number2 = " + number2);  // get the second number
            switch (operator) {   // I replaced your if statements with that switch (but it is actually the same)
                case '+':
                    number1 += number2;  // we add the second number to the first number and "store" the result in the first number
                    break;
                case '-':
                    number1 -= number2;
                    break;
                case '*':
                    number1 *= number2;
                    break;
                case '/':
                    number1 /= number2;
                    break;
            }
        } catch (java.lang.IndexOutOfBoundsException e) {  // here we break out of the loop. We can be 100% sure that at some point we reached the end of the list. So when we are at the end of the list and try to access the "next" element of the list (which does of course not exist) we get that IndexOutOfBoundsException and we know, we are finished here
            System.out.println("result is " + number1);
            break;  // break out of the loop
        }
    }
}

这里的重要部分实际上是我们在第一个数字中存储两个数字的任何操作的结果。因此,如果我们有1+2+4,则会首先评估1+2,将结果存储为第一个数字,然后评估3+4

辅助方法 现在我们仍然需要方法来检测运算符或数字;

private static char getNextOperator(ArrayList<String> sequence) {
    String function = "[+\\-*/]+";   // the same regex as before to detect any operator
    // with a list it looks like this
    // list.get(0) is the same as array[0]

    if (sequence.get(0).matches(function)) {  
        return sequence.remove(0).charAt(0);  
    }
    return ' ';
}

这里使用了一个很好的技巧:sequence.get(0)将查看列表中的第一个元素并返回其值。但是sequence.remove(0)将返回其值并同时从列表中删除该元素。所以原来的第一个元素将不再存在,而之前的第二个元素将成为第一个......

首先,我们的列表看起来像{ "-", "2"},在调用getNextOperator()后,它看起来像{"2"},因为我们删除了运算符。

我们也是如此,以获得下一个数字:

private static double getNextNumber(ArrayList<String> sequence) {
    String sign = "[+-]+";   // regex to test if a string is only a sign (+ or -)
    String number = "[\\d,.]+";  //regex to test if a String is a number (with or without . or  ,
    double number1 = 0;
    if (sequence.get(0).matches(sign) && sequence.get(1).matches(number)) {
        // first one should be a sign and the second one a number
        number1 = Double.parseDouble(sequence.remove(0) + sequence.remove(0));
    } else if (sequence.get(0).matches(number)) {
        // its a normal number
        number1 = Double.parseDouble(sequence.remove(0));
    }
    return number1;
}

嗯,就是这样。现在你只需要将它们放在一起并在你的主函数中调用它:

public static void main(String[] args) {
    try (Scanner console = new Scanner(System.in)) {
        String input;

        System.out.print(">>> ");
        input = console.nextLine();
        ArrayList<String> sequence = getSequence(input);  // analyze input and get a list
        evaluate(sequence);  // evaluate the list
        System.out.println("The console is now closed.");
    }
}

嗯,抱歉改变这么多。我想不出另一种(也许更有效)的方式来做到这一点。这个计算器现在不是很“聪明”,有很多东西它不会处理(如字母或大括号),但我希望它是一个开始。至少现在应该使用负数和正数,它应该能够处理更长的方程式。

喝彩!