Проблема с программой Java Calculator

Я пытаюсь разработать программу-калькулятор, которая вводит арифметическое выражение формы number operator number = и вычисляет результат выражения. Выражение будет оцениваться слева направо без учета приоритета обычного оператора. Например, выражение 14 - 5 * 3 = даст 27.0. Значение = отображает окончательный результат и завершает работу программы.

Я пытался исправить это уже пару дней, но он выводит неправильный ответ всякий раз, когда я ввожу выражение с более чем двумя числами. Например, 2.8 + 2 - 9.5 должно равняться -4.7, но программа выводит -6.7. Любая идея, почему это так?

import java.util.Scanner;

public class Calculator {

    // Compute an arithmetic expression 
    public static void main(String[] args) {
        // Declare the identifiers
        final String END = " = ";
        String input;
        double num1 = 0;
        double num2 = 0;
        char operator = 0;
        
        Scanner scnr = new Scanner (System.in);
        
        System.out.println("Enter your numeric expression in the following form: ");
        System.out.println("number operator number operator number = ");
        System.out.println("Leave a blank space after each number or operator.");
        System.out.println("Example: 3.5 * 3 - 5 / 2.5  = ");

        // Input the first item
        System.out.print("> ");
        input = scnr.next();
        
        // Process the first item and input and process the rest of the items 
        while (!input.equals(END)){
            switch (input){
                case "+":               
                    operator = '+';
                    System.out.println("> Operator is: " + operator);
                    break;
                case "-":               
                    operator = '-';
                    System.out.println("> Operator is: " + operator);
                    break;
                case "*": 
                    operator = '*';
                    System.out.println("> Operator is: " + operator);
                    break;
                case "/": 
                    operator = '/';
                    System.out.println("> Operator is: " + operator);
                    break;                  
                default: // a number was entered
                    if (num1 == 0) {
                        num1 = Double.parseDouble(input);
                        System.out.println("> Num1 is: " + num1);
                    }
                    else {
                        num2 = Double.parseDouble(input);
                        System.out.println("> Num2 is: " + num2);
                    }
                    
            } // end of switch
            
            if (num1 != 0 && num2 != 0) {
                
                System.out.println("Num2 before calc is " + num2);
                
                switch (operator) {
                    case '+':               
                        num2 = num1 + num2;
                        break;
                    case '-':               
                        num2 = num1 - num2;
                        break;
                    case '*': 
                        num2 = num1 * num2;
                        break;
                    case '/': 
                        num2 = num1 / num2;
                        break;
                    default:
                }
            }
            input = scnr.next();
            
        } // end of while-loop
        
        // Display the answer
        System.out.println("> Answer is: " + num2);
        
        
        
        System.out.println("Have a nice day!");
        
    }
}

Просто просмотрите свой код и спросите себя, какие значения будет иметь каждая переменная после каждого шага. Или запустить под отладчиком. В частности, после того, как «2,8 + 2» были введены и сложены, куда пойдет сумма, и куда пойдет следующее число (9,5), и каковы будут операнды при вычитании?

David Conrad 24.03.2022 00:31

Также обратите внимание: даже для ваших уменьшенных требований вы не выполняете правильный синтаксический анализ. Что, если пользователь введет 0 + 1 ... тогда ваш код завершится ошибкой, потому что num1 станет равным 0, и вы используете это как маркер, что говорит вам, что вы все еще ожидаете первого операнда. Настоящим ответом может быть: примите, что это сложнее, чем вы думали, а затем решите, хотите ли вы ДЕЙСТВИТЕЛЬНО понять и решить эту проблему. Если это так, обратитесь к хорошему учебнику, например blog.mbedded.ninja/programming/algorithms-and-data-structure‌​s/….

GhostCat 24.03.2022 17:25

По этой ссылке перечислены ключевые термины, которые важны для вас, и которые вы затем можете исследовать один за другим.

GhostCat 24.03.2022 17:26
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я немного изменил ваш ордер и сбросил переменную удержания.

public static void main(String[] args) {
     // Declare the identifiers
    final String END = " = ";
    String input;
    double num1 = 0;
    double num2 = 0;
    char operator = 0;
    
    Scanner scnr = new Scanner (System.in);
    
    System.out.println("Enter your numeric expression in the following form: ");
    System.out.println("number operator number operator number = ");
    System.out.println("Leave a blank space after each number or operator.");
    System.out.println("Example: 3.5 * 3 - 5 / 2.5  = ");

    // Input the first item
    System.out.print("> ");
    input = scnr.next();
    
    // Process the first item and input and process the rest of the items 
    while (!input.equals(END)){
        switch (input){
            case "+":               
                operator = '+';
                System.out.println("> Operator is: " + operator);
                break;
            case "-":               
                operator = '-';
                System.out.println("> Operator is: " + operator);
                break;
            case "*": 
                operator = '*';
                System.out.println("> Operator is: " + operator);
                break;
            case "/": 
                operator = '/';
                System.out.println("> Operator is: " + operator);
                break;                  
            default: // a number was entered
                if (num1 == 0) {
                    num1 = Double.parseDouble(input);
                    System.out.println("> Num1 is: " + num1);
                } else {
                    num2 = Double.parseDouble(input);
                    System.out.println("> Num2 is: " + num2);
                }
                
        } // end of switch
        
        if (num1 != 0 && num2 != 0) {
            
            System.out.println(String.format("Num1 : %.3f, Num2: %.3f", num1, num2));
            
            switch (operator) {
                case '+':               
                    num1 = num1 + num2;
                    num2 = 0;
                    break;
                case '-':               
                    num1 = num1 - num2;
                    num2 = 0;
                    break;
                case '*': 
                    num1 = num1 * num2;
                    num2 = 0;
                    break;
                case '/': 
                    num1 = num1 / num2;
                    num2 = 0;
                    break;
                default:
            }
        }
        input = scnr.next();
        
    } // end of while-loop
    
    // Display the answer
    System.out.println("> Answer is: " + num1);
}

Вопрос с подвохом: что происходит при вводе типа 0 + 1

GhostCat 24.03.2022 17:27

Это его код, я просто заставил его работать так, как он задумал. Я бы использовал Double и установил для него значение null вместо 0.

Ryan 24.03.2022 18:09
Ответ принят как подходящий

Чтобы заставить его работать, попробуйте:

  • во втором операторе switch измените num2 = num1 + num2; на num1 = num1 + num2;. Сделайте это для всех случаев;
  • Я добавил логическое значение isOperator, чтобы пропустить вычисление операции, если ввод является оператором.

Полный код ниже:

import java.util.Scanner;

public class Calculator {

    // Compute an arithmetic expression 
    public static void main(String[] args) {
        // Declare the identifiers
        final String END = " = ";
        String input;
        double num1 = 0;
        double num2 = 0;
        char operator = 0;
        boolean isOperator;
        
        Scanner scnr = new Scanner (System.in);
        
        System.out.println("Enter your numeric expression in the following form: ");
        System.out.println("number operator number operator number = ");
        System.out.println("Leave a blank space after each number or operator.");
        System.out.println("Example: 3.5 * 3 - 5 / 2.5  = ");

        // Input the first item
        System.out.print("> ");
        input = scnr.next();
        
        // Process the first item and input and process the rest of the items 
        while (!input.equals(END)){
            isOperator = true;
            switch (input){
                case "+":               
                    operator = '+';
                    System.out.println("> Operator is: " + operator);
                    break;
                case "-":               
                    operator = '-';
                    System.out.println("> Operator is: " + operator);
                    break;
                case "*": 
                    operator = '*';
                    System.out.println("> Operator is: " + operator);
                    break;
                case "/": 
                    operator = '/';
                    System.out.println("> Operator is: " + operator);
                    break;                  
                default: // a number was entered
                    isOperator = false;
                    if (num1 == 0) {
                        num1 = Double.parseDouble(input);
                        System.out.println("> Num1 is: " + num1);
                    }
                    else {
                        num2 = Double.parseDouble(input);
                        System.out.println("> Num2 is: " + num2);
                    }
                    
            } // end of switch
            
            // do not compute the operation if the input is an operator and num1,num2 != 0
            if (num1 != 0 && num2 != 0 && !isOperator) {
                
                System.out.println("Num2 before calc is " + num2);
                
                switch (operator) {
                    case '+':               
                        num1 = num1 + num2;
                        break;
                    case '-':               
                        num1 = num1 - num2;
                        break;
                    case '*': 
                        num1 = num1 * num2;
                        break;
                    case '/': 
                        num1 = num1 / num2;
                        break;
                    default:
                }
            }
            input = scnr.next();
            
        } // end of while-loop
        
        // Display the answer
        System.out.println("> Answer is: " + num1);
        
        
        
        System.out.println("Have a nice day!");
        
    }
}

Редактировать: Как упоминалось в комментариях, код не обрабатывает случаи, когда пользователь вводит 0. Ниже я удалил условия if (num1 == 0) и if (num1 != 0 && num2 != 0):

import java.util.Scanner;

public class Calculator {

    // Compute an arithmetic expression 
    public static void main(String[] args) {
        // Declare the identifiers
        final String END = " = ";
        String input;
        double result = 0;
        double num = 0;
        char operator = 0;
        boolean isOperator;
        
        Scanner scnr = new Scanner (System.in);
        
        System.out.println("Enter your numeric expression in the following form: ");
        System.out.println("number operator number operator number = ");
        System.out.println("Leave a blank space after each number or operator.");
        System.out.println("Example: 3.5 * 3 - 5 / 2.5  = ");

        // Input the first item
        System.out.print("> ");
        input = scnr.next();
        
        // Process the first item and input and process the rest of the items 
        while (!input.equals(END)){
            isOperator = true;
            switch (input){
                case "+":               
                    operator = '+';
                    System.out.println("> Operator is: " + operator);
                    break;
                case "-":               
                    operator = '-';
                    System.out.println("> Operator is: " + operator);
                    break;
                case "*": 
                    operator = '*';
                    System.out.println("> Operator is: " + operator);
                    break;
                case "/": 
                    operator = '/';
                    System.out.println("> Operator is: " + operator);
                    break;                  
                default: // a number was entered
                    isOperator = false;
                    num = Double.parseDouble(input);
                    System.out.println("> Num is: " + num);
            } // end of switch
            
            // do not compute the operation if the input is an operator
            if (!isOperator) {
                
                System.out.println("Result before calc is " + result);
                
                switch (operator) {
                    case '+':               
                        result += num;
                        break;
                    case '-':               
                        result -= num;
                        break;
                    case '*': 
                        result *= num;
                        break;
                    case '/': 
                        result /= num;
                        break;
                    default:
                        result += num;
                }
            }
            input = scnr.next();
            
        } // end of while-loop
        
        // Display the answer
        System.out.println("> Answer is: " + result);
        
        
        
        System.out.println("Have a nice day!");
        
    }
}

Спросите себя, что происходит, когда кто-то входит: 0 + 1

GhostCat 24.03.2022 17:24

Спасибо, что указали на это, нет необходимости в условиях num == 0. Я добавил второй фрагмент кода.

happy songs 24.03.2022 18:32

Верно, это работает. Конечно, он сломается, как только появится приоритет оператора.

GhostCat 24.03.2022 20:50

Другие вопросы по теме