Я пытаюсь разработать программу-калькулятор, которая вводит арифметическое выражение формы 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!");
}
}
Также обратите внимание: даже для ваших уменьшенных требований вы не выполняете правильный синтаксический анализ. Что, если пользователь введет 0 + 1 ... тогда ваш код завершится ошибкой, потому что num1 станет равным 0, и вы используете это как маркер, что говорит вам, что вы все еще ожидаете первого операнда. Настоящим ответом может быть: примите, что это сложнее, чем вы думали, а затем решите, хотите ли вы ДЕЙСТВИТЕЛЬНО понять и решить эту проблему. Если это так, обратитесь к хорошему учебнику, например blog.mbedded.ninja/programming/algorithms-and-data-structures/….
По этой ссылке перечислены ключевые термины, которые важны для вас, и которые вы затем можете исследовать один за другим.




Я немного изменил ваш ордер и сбросил переменную удержания.
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
Это его код, я просто заставил его работать так, как он задумал. Я бы использовал Double и установил для него значение null вместо 0.
Чтобы заставить его работать, попробуйте:
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
Спасибо, что указали на это, нет необходимости в условиях num == 0. Я добавил второй фрагмент кода.
Верно, это работает. Конечно, он сломается, как только появится приоритет оператора.
Просто просмотрите свой код и спросите себя, какие значения будет иметь каждая переменная после каждого шага. Или запустить под отладчиком. В частности, после того, как «2,8 + 2» были введены и сложены, куда пойдет сумма, и куда пойдет следующее число (9,5), и каковы будут операнды при вычитании?