创建计算器但无法退出
Creating a calculator but can't exit
我需要编码方面的帮助。我正在再次练习我的 java 编程,今天我正在创建一个与真实计算器具有相同功能的计算器,但我再次 运行 出错,无法再次计算。
好的,我希望我的计算器工作的方式不是像这样从用户那里逐行输入:-
在代码输出中
Enter Number: 1
Enter Operator (+,-, /, *, ^ (Power) or s (Square): +
Enter Number: 2
Ans: 3
我想让它计算用户按下回车键的时间:-
我想要的输出
enter number: 1+2*4
Ans: 12
所以他们可以在点击输入计算之前添加任意多的长数字。用户应该能够在计算循环中使用计算器时将数字重置为。
在代码的开头,它会要求用户输入以继续或退出计算器。然后,如果继续,它将 运行 计算。计算器将一直循环,直到用户按 E 退出计算器,如果退出,它将退出代码。
这是我有错误的地方。首先,当用户按下 E[=38= 时,我无法弄清楚 如何在循环计算器 和代码开头的第二个 中中断循环] 它应该退出计算器但它没有。第三个错误是当用户使用平方来计算时我希望它直接显示答案而不是询问另一个数字。
并且我想简化 public static void main(String[] args)
中计算部分的代码。是否可以将 switch case 放在方法中并在 main 中调用它?或者您对如何简化计算部分有什么建议吗?
请帮帮我:(
public class TestingCalculator {
public static void main(String[] args){
double answer = 0;
double numA, numB;
char operator;
char activateCalc;
boolean calculator = false;
System.out.println("Welcome to the Calculator.");
System.out.print(" Continue (Press Y) \n Exit (Press E) \n: ");
Scanner ans = new Scanner(System.in);
String a = ans.next();
activateCalc = a.charAt(0);
while (activateCalc != 'E' || activateCalc != 'e') {
Scanner input = new Scanner(System.in);
System.out.print("Enter number: ");
String n =input.next();
numA = Double.parseDouble(n);
while (calculator = true) {
//User enter their operator.
System.out.print("Enter Operator (+,-, /, *, ^ (Power) or s (Square): ");
operator = input.next().charAt(0);
System.out.print("Enter number: "); //User enter the continues number
numB = input.nextDouble();
switch (operator) {
case '=':
System.out.print(answer);
break;
case '+':
answer = add(numA,numB);
break;
case '-':
answer =subtract(numA,numB);
break;
case '*':
answer = multiply(numA,numB);
break;
case '/':
answer = divide(numA,numB);
break;
case '^':
answer = power(numA, numB);
break;
case 's':
case 'S':
answer = Math.pow(numA, 2);
break;
}
//The calculation answer of the user input
System.out.println("Answer: " + answer);
numA = answer;
// to exit calculator.
System.out.println("Press E to Exit the calculator: ");
if (activateCalc = 'E' || activateCalc = 'e') {
break;
}
}
}
ans.close();
}
//Method for the operators.
static double add(double numA, double numB) {
double answer = numA + numB;
return answer;
}
static double subtract(double numA, double numB) {
double answer = numA - numB;
return answer;
}
static double multiply(double numA, double numB) {
double answer = numA * numB;
return answer;
}
static double divide(double numA, double numB) {
double answer = numA / numB;
return answer;
}
static double power(double numA, double numB) {
int answer = (int) Math.pow(numA, numB);
return answer;
}
static double Square(double numA, double numB) {
int answer = (int) Math.pow(numA, 2);
return answer;
}
}
尝试下面的代码和一个建议来尝试处理负面情况。
public static void main(String[] args) {
double answer = 0;
double numA, numB;
char operator;
char activateCalc;
boolean calculator = false;
System.out.println("Welcome to the Calculator.");
System.out.print(" Continue (Press Y) \n Exit (Press E) \n: ");
Scanner ans = new Scanner(System.in);
Scanner input = new Scanner(System.in);
activateCalc = input.next().charAt(0);
while (true) {
if (activateCalc != 'E' && activateCalc != 'e') {
System.out.print("Enter number: ");
String n = input.next();
numA = Double.parseDouble(n);
// User enter their operator.
System.out.print("Enter Operator (+,-, /, *, ^ (Power) or s (Square): ");
operator = input.next().charAt(0);
System.out.print("Enter number: "); // User enter the continues number
numB = input.nextDouble();
switch (operator) {
case '=':
System.out.print(answer);
break;
case '+':
answer = add(numA, numB);
break;
case '-':
answer = subtract(numA, numB);
break;
case '*':
answer = multiply(numA, numB);
break;
case '/':
answer = divide(numA, numB);
break;
case '^':
answer = power(numA, numB);
break;
case 'S':
case 's':
answer = Math.pow(numA, 2);
break;
default:
answer = 0;
}
// The calculation answer of the user input
System.out.println("Answer: " + answer);
numA = answer;
// to exit calculator.
System.out.println("Press E to Exit the calculator or Y to continue : ");
activateCalc = input.next().charAt(0);
if(activateCalc != 'E' && activateCalc != 'e')continue;
}
System.out.println("Thank you for using the calculator. By :) ");
ans.close();
break;
}
}
// Method for the operators.
static double add(double numA, double numB) {
double answer = numA + numB;
return answer;
}
static double subtract(double numA, double numB) {
double answer = numA - numB;
return answer;
}
static double multiply(double numA, double numB) {
double answer = numA * numB;
return answer;
}
static double divide(double numA, double numB) {
double answer = numA / numB;
return answer;
}
static double power(double numA, double numB) {
int answer = (int) Math.pow(numA, numB);
return answer;
}
static double Square(double numA, double numB) {
int answer = (int) Math.pow(numA, 2);
return answer;
}
这个问题需要调试细节,所以我们开始:
- 由于错误,您的代码似乎无法编译:
if (activateCalc = 'E' || activateCalc = 'e') {
break;
}
您必须使用比较 ==
运算符而不是赋值 =
。
类似的问题在您的内部循环中 while (calculator = true)
- 并且有一个警告说这个值从未被使用过 - 但这不会影响太大。
你不能退出循环,因为你从不检查退出的输入,它应该是:
System.out.println("Press E to Exit the calculator: ");
activateCalc = input.next().charAt(0);
- 但是,即使您更新了
activateCalc
,由于这种情况 while (activateCalc != 'E' || activateCalc != 'e')
中的错误,您仍然会进入无限循环——即使用户按下 'e',或 'E' 这个条件总是成立的。
我决定专注于生成一个按您希望的方式(使用您指定的输入)工作的程序,而不是试图找出您的应用程序的问题。代码有点大,但我试着对其进行了很好的注释,以便您了解我所做的事情。我知道有些事情可能仍然有点令人困惑,所以我将模拟 运行 程序以尝试使其更清楚它是如何工作的。
代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class TestingCalculator
{
//-------------------------------------------------------------------------
// Methods
//-------------------------------------------------------------------------
/**
* Evaluates a mathematical expression.
*
* @param line Mathematical expression. This line cannot have blank
* spaces
* @return Result of this mathematical expression
*/
public static String calc(String line)
{
while (!hasOnlyNumbers(line)) {
// Checks if line has parentheses
if (line.contains("(")) {
// Get index of the most nested parentheses
int parentheses_begin = line.lastIndexOf("(");
int parentheses_end = line.substring(parentheses_begin).indexOf(")");
String ans = calc(line.substring(parentheses_begin+1, parentheses_end));
// Replaces content of parentheses with the result obtained
if (line.length()-1 >= parentheses_end+1)
line = line.substring(0,parentheses_begin)+ans+line.substring(parentheses_end+1);
else
line = line.substring(0,parentheses_begin)+ans;
}
// Checks if line has potentiation operator
else if (line.contains("^")) {
int opIndex = line.indexOf("^");
String n1 = extractFirstNumber(line, opIndex);
String n2 = extractSecondNumber(line, opIndex);
double ans = power(Double.valueOf(n1), Double.valueOf(n2));
line = calc(parseLine(line, n1, n2, opIndex, ans));
}
// Checks if line has square operator
else if (line.contains("s")) {
int opIndex = line.indexOf("s");
String n1 = extractFirstNumber(line, opIndex);
double ans = square(Double.valueOf(n1));
line = calc(parseLine(line, n1, opIndex, ans));
}
// Checks if line has multiplication operator
else if (line.contains("*")) {
int opIndex = line.indexOf("*");
String n1 = extractFirstNumber(line, opIndex);
String n2 = extractSecondNumber(line, opIndex);
double ans = multiply(Double.valueOf(n1), Double.valueOf(n2));
line = calc(parseLine(line, n1, n2, opIndex, ans));
}
// Checks if line has division operator
else if (line.contains("/")) {
int opIndex = line.indexOf("/");
String n1 = extractFirstNumber(line, opIndex);
String n2 = extractSecondNumber(line, opIndex);
double ans = divide(Double.valueOf(n1), Double.valueOf(n2));
line = calc(parseLine(line, n1, n2, opIndex, ans));
}
// Checks if line has sum operator
else if (line.contains("+")) {
int opIndex = line.indexOf("+");
String n1 = extractFirstNumber(line, opIndex);
String n2 = extractSecondNumber(line, opIndex);
double ans = add(Double.valueOf(n1), Double.valueOf(n2));
line = calc(parseLine(line, n1, n2, opIndex, ans));
}
// Checks if line has subtraction operator
else if (line.contains("-")) {
int opIndex = line.indexOf("-");
String n1 = extractFirstNumber(line, opIndex);
String n2 = extractSecondNumber(line, opIndex);
double ans = subtract(Double.valueOf(n1), Double.valueOf(n2));
line = calc(parseLine(line, n1, n2, opIndex, ans));
}
}
// Returns line only when it has only numbers
return line;
}
/**
* Checks if a line contains only numbers.
*
* @param line Line to be analyzed
* @return If a line contains only numbers
*/
private static boolean hasOnlyNumbers(String line)
{
return line.matches("^[0-9.]+$");
}
/**
* Given a mathematical expression, replaces a subexpression for a value.
*
* @param line Mathematical expression
* @param n1 Number to the left of the subexpression operator
* @param n2 Number to the right of the subexpression operator
* @param opIndex Operator index of the subexpression
* @param ans Value that will replace the subexpression
* @return New mathematical expression with the subexpression replaced
* by the value
*/
private static String parseLine(String line, String n1, String n2, int opIndex, double ans)
{
int lenFirstNumber = n1.length();
int lenSecondNumber = n2.length();
if (line.length()-1 >= opIndex+lenSecondNumber+1)
return line.substring(0, opIndex-lenFirstNumber)+ans+line.substring(opIndex+lenSecondNumber+1);
return line.substring(0, opIndex-lenFirstNumber)+ans;
}
/**
* Given a mathematical expression, replaces a subexpression for a value.
*
* @param line Mathematical expression
* @param n1 Number to the left of the subexpression operator
* @param opIndex Operator index of the subexpression
* @param ans Value that will replace the subexpression
* @return New mathematical expression with the subexpression replaced
* by the value
*/
private static String parseLine(String line, String n1, int opIndex, double ans)
{
int lenFirstNumber = n1.length();
if (line.length()-1 >= opIndex+2)
return line.substring(0, opIndex-lenFirstNumber)+ans+line.substring(opIndex+2);
return line.substring(0, opIndex-lenFirstNumber)+ans;
}
/**
* Extracts the first number from an operation. <br />
* <h1>Example:<h1> <br />
* <b>Line:</b> 1+2*3 <br />
* <b>opIndex:</b> 3 <br />
* <b>Return:</b> 2 <br />
*
* @param line Mathematical expression
* @param opIndex Index of the operator to which the number to be
* extracted belongs to
* @return Number to the left of the operator
*/
private static String extractFirstNumber(String line, int opIndex)
{
StringBuilder num = new StringBuilder();
int i = opIndex-1;
while (i>=0 && (Character.isDigit(line.charAt(i)) || line.charAt(i) == '.')) {
num.append(line.charAt(i));
i--;
}
// Reverses the result, since the number is taken from the end to the
// beginning
num = num.reverse();
return num.toString();
}
/**
* Extracts the second number from a math operation. <br />
* <h1>Example:<h1> <br />
* <b>Line:</b> 1+2*3 <br />
* <b>opIndex:</b> 3 <br />
* <b>Return:</b> 3 <br />
*
* @param line Mathematical expression
* @param opIndex Index of the operator to which the number to be
* extracted belongs to
* @return Number to the right of the operator
*/
private static String extractSecondNumber(String line, int opIndex)
{
StringBuilder num = new StringBuilder();
int i = opIndex+1;
while (i<line.length() && (Character.isDigit(line.charAt(i)) || line.charAt(i) == '.')) {
num.append(line.charAt(i));
i++;
}
return num.toString();
}
// Method for the operators.
private static double add(double numA, double numB)
{
double answer = numA + numB;
return answer;
}
private static double subtract(double numA, double numB)
{
double answer = numA - numB;
return answer;
}
private static double multiply(double numA, double numB)
{
double answer = numA * numB;
return answer;
}
private static double divide(double numA, double numB)
{
double answer = numA / numB;
return answer;
}
private static double power(double numA, double numB)
{
int answer = (int) Math.pow(numA, numB);
return answer;
}
private static double square(double num)
{
int answer = (int) Math.pow(num, 2);
return answer;
}
//-------------------------------------------------------------------------
// Main
//-------------------------------------------------------------------------
public static void main(String[] args) throws IOException
{
char option;
String inputLine = "";
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Welcome to the Calculator.");
System.out.print(" Continue (Press Y) \n Exit (Press E) \n: ");
option = input.readLine().charAt(0);
while (option != 'E' && option != 'e') {
// Gets user input
System.out.print("Enter mathematical expression: ");
inputLine += input.readLine();
// Processes input
inputLine = inputLine.replaceAll(" ", "");
inputLine = inputLine.replaceAll("S", "s");
// Evaluates input
System.out.println("Evaluating...");
String ans = TestingCalculator.calc(inputLine);
// Displays answer
System.out.println("Ans: "+ans);
// Checks if the user wants to continue running the program
System.out.print("Press E to Exit the calculator: ");
inputLine = input.readLine();
if (inputLine.length() > 0)
option = inputLine.charAt(0);
}
input.close();
}
}
输出
Enter mathematical expression: (1+2*4)/3
Evaluating...
Ans: 3.0
输出 2
Enter mathematical expression: 1+2*9/3
Evaluating...
Ans: 7.0
案头检查
输入: (1+2*4)/3
calc( (1+2*4)/3 )
not hasOnlyNumbers( (1+2*4)/3) ) ? true
( (1+2*4)/3) ) contains '(' ? true
int parentheses_begin = 0
int parentheses_end = 6
String ans = calc( 1+2*4 )
calc( 1+2*4 )
not hasOnlyNumbers( 1+2*4 ) ? true
( 1+2*4 ) contains '(' ? false
( 1+2*4 ) contains '^' ? false
( 1+2*4 ) contains 's' ? false
( 1+2*4 ) contains '*' ? true
int opIndex = 3
int n1 = 2
int n2 = 4
String ans = n1 * n2 = 2 * 4 = 8
line = calc( 1+8 )
calc( 1+8 )
not hasOnlyNumbers( 1+8 ) ? true
( 1+8 ) contains '(' ? false
( 1+8 ) contains '^' ? false
( 1+8 ) contains 's' ? false
( 1+8 ) contains '*' ? false
( 1+8 ) contains '/' ? false
( 1+8 ) contains '+' ? true
int opIndex = 1
int n1 = 1
int n2 = 8
String ans = n1 + n2 = 1 + 8 = 9
line = calc( 9 )
calc( 9 )
not hasOnlyNumbers( 9 ) ? false
return 9
line = 9
not hasOnlyNumbers( 9 ) ? false
return 9
line = 9
not hasOnlyNumbers( 9 ) ? false
return 9
ans = 9
(9-1 >= 6+1) ? true
line = 9/3
not hasOnlyNumbers( 9/3 ) ? true
( 9/3 ) contains '(' ? false
( 9/3 ) contains '^' ? false
( 9/3 ) contains 's' ? false
( 9/3 ) contains '*' ? false
( 9/3 ) contains '/' ? true
int opIndex = 1
String n1 = 9
String n2 = 3
double ans = 9 / 3 = 3
line = calc( 3 )
calc( 3 )
not hasOnlyNumbers( 3 ) ? false
return 3
line = 3
not hasOnlyNumbers( 3 ) ? false
return 3
一些观察
- 不检查用户提供的输入是否有效
- 重要的是保持在 calc 方法中验证的运算顺序,以保持运算符之间的优先级(必须先进行求幂/除法,然后是乘法/除法,最后是加法/减法运算)
- 我的扫描仪有问题class,所以我使用 BufferedReader 读取输入
- 平方运算必须按如下方式进行:
s或 S
希望这对您有所帮助。如果你有什么不明白的地方,告诉我,我可以解释给你听。
我需要编码方面的帮助。我正在再次练习我的 java 编程,今天我正在创建一个与真实计算器具有相同功能的计算器,但我再次 运行 出错,无法再次计算。
好的,我希望我的计算器工作的方式不是像这样从用户那里逐行输入:-
在代码输出中
Enter Number: 1
Enter Operator (+,-, /, *, ^ (Power) or s (Square): +
Enter Number: 2
Ans: 3
我想让它计算用户按下回车键的时间:-
我想要的输出
enter number: 1+2*4
Ans: 12
所以他们可以在点击输入计算之前添加任意多的长数字。用户应该能够在计算循环中使用计算器时将数字重置为。
在代码的开头,它会要求用户输入以继续或退出计算器。然后,如果继续,它将 运行 计算。计算器将一直循环,直到用户按 E 退出计算器,如果退出,它将退出代码。
这是我有错误的地方。首先,当用户按下 E[=38= 时,我无法弄清楚 如何在循环计算器 和代码开头的第二个 中中断循环] 它应该退出计算器但它没有。第三个错误是当用户使用平方来计算时我希望它直接显示答案而不是询问另一个数字。
并且我想简化 public static void main(String[] args)
中计算部分的代码。是否可以将 switch case 放在方法中并在 main 中调用它?或者您对如何简化计算部分有什么建议吗?
请帮帮我:(
public class TestingCalculator {
public static void main(String[] args){
double answer = 0;
double numA, numB;
char operator;
char activateCalc;
boolean calculator = false;
System.out.println("Welcome to the Calculator.");
System.out.print(" Continue (Press Y) \n Exit (Press E) \n: ");
Scanner ans = new Scanner(System.in);
String a = ans.next();
activateCalc = a.charAt(0);
while (activateCalc != 'E' || activateCalc != 'e') {
Scanner input = new Scanner(System.in);
System.out.print("Enter number: ");
String n =input.next();
numA = Double.parseDouble(n);
while (calculator = true) {
//User enter their operator.
System.out.print("Enter Operator (+,-, /, *, ^ (Power) or s (Square): ");
operator = input.next().charAt(0);
System.out.print("Enter number: "); //User enter the continues number
numB = input.nextDouble();
switch (operator) {
case '=':
System.out.print(answer);
break;
case '+':
answer = add(numA,numB);
break;
case '-':
answer =subtract(numA,numB);
break;
case '*':
answer = multiply(numA,numB);
break;
case '/':
answer = divide(numA,numB);
break;
case '^':
answer = power(numA, numB);
break;
case 's':
case 'S':
answer = Math.pow(numA, 2);
break;
}
//The calculation answer of the user input
System.out.println("Answer: " + answer);
numA = answer;
// to exit calculator.
System.out.println("Press E to Exit the calculator: ");
if (activateCalc = 'E' || activateCalc = 'e') {
break;
}
}
}
ans.close();
}
//Method for the operators.
static double add(double numA, double numB) {
double answer = numA + numB;
return answer;
}
static double subtract(double numA, double numB) {
double answer = numA - numB;
return answer;
}
static double multiply(double numA, double numB) {
double answer = numA * numB;
return answer;
}
static double divide(double numA, double numB) {
double answer = numA / numB;
return answer;
}
static double power(double numA, double numB) {
int answer = (int) Math.pow(numA, numB);
return answer;
}
static double Square(double numA, double numB) {
int answer = (int) Math.pow(numA, 2);
return answer;
}
}
尝试下面的代码和一个建议来尝试处理负面情况。
public static void main(String[] args) {
double answer = 0;
double numA, numB;
char operator;
char activateCalc;
boolean calculator = false;
System.out.println("Welcome to the Calculator.");
System.out.print(" Continue (Press Y) \n Exit (Press E) \n: ");
Scanner ans = new Scanner(System.in);
Scanner input = new Scanner(System.in);
activateCalc = input.next().charAt(0);
while (true) {
if (activateCalc != 'E' && activateCalc != 'e') {
System.out.print("Enter number: ");
String n = input.next();
numA = Double.parseDouble(n);
// User enter their operator.
System.out.print("Enter Operator (+,-, /, *, ^ (Power) or s (Square): ");
operator = input.next().charAt(0);
System.out.print("Enter number: "); // User enter the continues number
numB = input.nextDouble();
switch (operator) {
case '=':
System.out.print(answer);
break;
case '+':
answer = add(numA, numB);
break;
case '-':
answer = subtract(numA, numB);
break;
case '*':
answer = multiply(numA, numB);
break;
case '/':
answer = divide(numA, numB);
break;
case '^':
answer = power(numA, numB);
break;
case 'S':
case 's':
answer = Math.pow(numA, 2);
break;
default:
answer = 0;
}
// The calculation answer of the user input
System.out.println("Answer: " + answer);
numA = answer;
// to exit calculator.
System.out.println("Press E to Exit the calculator or Y to continue : ");
activateCalc = input.next().charAt(0);
if(activateCalc != 'E' && activateCalc != 'e')continue;
}
System.out.println("Thank you for using the calculator. By :) ");
ans.close();
break;
}
}
// Method for the operators.
static double add(double numA, double numB) {
double answer = numA + numB;
return answer;
}
static double subtract(double numA, double numB) {
double answer = numA - numB;
return answer;
}
static double multiply(double numA, double numB) {
double answer = numA * numB;
return answer;
}
static double divide(double numA, double numB) {
double answer = numA / numB;
return answer;
}
static double power(double numA, double numB) {
int answer = (int) Math.pow(numA, numB);
return answer;
}
static double Square(double numA, double numB) {
int answer = (int) Math.pow(numA, 2);
return answer;
}
这个问题需要调试细节,所以我们开始:
- 由于错误,您的代码似乎无法编译:
if (activateCalc = 'E' || activateCalc = 'e') {
break;
}
您必须使用比较 ==
运算符而不是赋值 =
。
类似的问题在您的内部循环中
while (calculator = true)
- 并且有一个警告说这个值从未被使用过 - 但这不会影响太大。你不能退出循环,因为你从不检查退出的输入,它应该是:
System.out.println("Press E to Exit the calculator: ");
activateCalc = input.next().charAt(0);
- 但是,即使您更新了
activateCalc
,由于这种情况while (activateCalc != 'E' || activateCalc != 'e')
中的错误,您仍然会进入无限循环——即使用户按下 'e',或 'E' 这个条件总是成立的。
我决定专注于生成一个按您希望的方式(使用您指定的输入)工作的程序,而不是试图找出您的应用程序的问题。代码有点大,但我试着对其进行了很好的注释,以便您了解我所做的事情。我知道有些事情可能仍然有点令人困惑,所以我将模拟 运行 程序以尝试使其更清楚它是如何工作的。
代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class TestingCalculator
{
//-------------------------------------------------------------------------
// Methods
//-------------------------------------------------------------------------
/**
* Evaluates a mathematical expression.
*
* @param line Mathematical expression. This line cannot have blank
* spaces
* @return Result of this mathematical expression
*/
public static String calc(String line)
{
while (!hasOnlyNumbers(line)) {
// Checks if line has parentheses
if (line.contains("(")) {
// Get index of the most nested parentheses
int parentheses_begin = line.lastIndexOf("(");
int parentheses_end = line.substring(parentheses_begin).indexOf(")");
String ans = calc(line.substring(parentheses_begin+1, parentheses_end));
// Replaces content of parentheses with the result obtained
if (line.length()-1 >= parentheses_end+1)
line = line.substring(0,parentheses_begin)+ans+line.substring(parentheses_end+1);
else
line = line.substring(0,parentheses_begin)+ans;
}
// Checks if line has potentiation operator
else if (line.contains("^")) {
int opIndex = line.indexOf("^");
String n1 = extractFirstNumber(line, opIndex);
String n2 = extractSecondNumber(line, opIndex);
double ans = power(Double.valueOf(n1), Double.valueOf(n2));
line = calc(parseLine(line, n1, n2, opIndex, ans));
}
// Checks if line has square operator
else if (line.contains("s")) {
int opIndex = line.indexOf("s");
String n1 = extractFirstNumber(line, opIndex);
double ans = square(Double.valueOf(n1));
line = calc(parseLine(line, n1, opIndex, ans));
}
// Checks if line has multiplication operator
else if (line.contains("*")) {
int opIndex = line.indexOf("*");
String n1 = extractFirstNumber(line, opIndex);
String n2 = extractSecondNumber(line, opIndex);
double ans = multiply(Double.valueOf(n1), Double.valueOf(n2));
line = calc(parseLine(line, n1, n2, opIndex, ans));
}
// Checks if line has division operator
else if (line.contains("/")) {
int opIndex = line.indexOf("/");
String n1 = extractFirstNumber(line, opIndex);
String n2 = extractSecondNumber(line, opIndex);
double ans = divide(Double.valueOf(n1), Double.valueOf(n2));
line = calc(parseLine(line, n1, n2, opIndex, ans));
}
// Checks if line has sum operator
else if (line.contains("+")) {
int opIndex = line.indexOf("+");
String n1 = extractFirstNumber(line, opIndex);
String n2 = extractSecondNumber(line, opIndex);
double ans = add(Double.valueOf(n1), Double.valueOf(n2));
line = calc(parseLine(line, n1, n2, opIndex, ans));
}
// Checks if line has subtraction operator
else if (line.contains("-")) {
int opIndex = line.indexOf("-");
String n1 = extractFirstNumber(line, opIndex);
String n2 = extractSecondNumber(line, opIndex);
double ans = subtract(Double.valueOf(n1), Double.valueOf(n2));
line = calc(parseLine(line, n1, n2, opIndex, ans));
}
}
// Returns line only when it has only numbers
return line;
}
/**
* Checks if a line contains only numbers.
*
* @param line Line to be analyzed
* @return If a line contains only numbers
*/
private static boolean hasOnlyNumbers(String line)
{
return line.matches("^[0-9.]+$");
}
/**
* Given a mathematical expression, replaces a subexpression for a value.
*
* @param line Mathematical expression
* @param n1 Number to the left of the subexpression operator
* @param n2 Number to the right of the subexpression operator
* @param opIndex Operator index of the subexpression
* @param ans Value that will replace the subexpression
* @return New mathematical expression with the subexpression replaced
* by the value
*/
private static String parseLine(String line, String n1, String n2, int opIndex, double ans)
{
int lenFirstNumber = n1.length();
int lenSecondNumber = n2.length();
if (line.length()-1 >= opIndex+lenSecondNumber+1)
return line.substring(0, opIndex-lenFirstNumber)+ans+line.substring(opIndex+lenSecondNumber+1);
return line.substring(0, opIndex-lenFirstNumber)+ans;
}
/**
* Given a mathematical expression, replaces a subexpression for a value.
*
* @param line Mathematical expression
* @param n1 Number to the left of the subexpression operator
* @param opIndex Operator index of the subexpression
* @param ans Value that will replace the subexpression
* @return New mathematical expression with the subexpression replaced
* by the value
*/
private static String parseLine(String line, String n1, int opIndex, double ans)
{
int lenFirstNumber = n1.length();
if (line.length()-1 >= opIndex+2)
return line.substring(0, opIndex-lenFirstNumber)+ans+line.substring(opIndex+2);
return line.substring(0, opIndex-lenFirstNumber)+ans;
}
/**
* Extracts the first number from an operation. <br />
* <h1>Example:<h1> <br />
* <b>Line:</b> 1+2*3 <br />
* <b>opIndex:</b> 3 <br />
* <b>Return:</b> 2 <br />
*
* @param line Mathematical expression
* @param opIndex Index of the operator to which the number to be
* extracted belongs to
* @return Number to the left of the operator
*/
private static String extractFirstNumber(String line, int opIndex)
{
StringBuilder num = new StringBuilder();
int i = opIndex-1;
while (i>=0 && (Character.isDigit(line.charAt(i)) || line.charAt(i) == '.')) {
num.append(line.charAt(i));
i--;
}
// Reverses the result, since the number is taken from the end to the
// beginning
num = num.reverse();
return num.toString();
}
/**
* Extracts the second number from a math operation. <br />
* <h1>Example:<h1> <br />
* <b>Line:</b> 1+2*3 <br />
* <b>opIndex:</b> 3 <br />
* <b>Return:</b> 3 <br />
*
* @param line Mathematical expression
* @param opIndex Index of the operator to which the number to be
* extracted belongs to
* @return Number to the right of the operator
*/
private static String extractSecondNumber(String line, int opIndex)
{
StringBuilder num = new StringBuilder();
int i = opIndex+1;
while (i<line.length() && (Character.isDigit(line.charAt(i)) || line.charAt(i) == '.')) {
num.append(line.charAt(i));
i++;
}
return num.toString();
}
// Method for the operators.
private static double add(double numA, double numB)
{
double answer = numA + numB;
return answer;
}
private static double subtract(double numA, double numB)
{
double answer = numA - numB;
return answer;
}
private static double multiply(double numA, double numB)
{
double answer = numA * numB;
return answer;
}
private static double divide(double numA, double numB)
{
double answer = numA / numB;
return answer;
}
private static double power(double numA, double numB)
{
int answer = (int) Math.pow(numA, numB);
return answer;
}
private static double square(double num)
{
int answer = (int) Math.pow(num, 2);
return answer;
}
//-------------------------------------------------------------------------
// Main
//-------------------------------------------------------------------------
public static void main(String[] args) throws IOException
{
char option;
String inputLine = "";
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Welcome to the Calculator.");
System.out.print(" Continue (Press Y) \n Exit (Press E) \n: ");
option = input.readLine().charAt(0);
while (option != 'E' && option != 'e') {
// Gets user input
System.out.print("Enter mathematical expression: ");
inputLine += input.readLine();
// Processes input
inputLine = inputLine.replaceAll(" ", "");
inputLine = inputLine.replaceAll("S", "s");
// Evaluates input
System.out.println("Evaluating...");
String ans = TestingCalculator.calc(inputLine);
// Displays answer
System.out.println("Ans: "+ans);
// Checks if the user wants to continue running the program
System.out.print("Press E to Exit the calculator: ");
inputLine = input.readLine();
if (inputLine.length() > 0)
option = inputLine.charAt(0);
}
input.close();
}
}
输出
Enter mathematical expression: (1+2*4)/3
Evaluating...
Ans: 3.0
输出 2
Enter mathematical expression: 1+2*9/3
Evaluating...
Ans: 7.0
案头检查
输入: (1+2*4)/3
calc( (1+2*4)/3 ) not hasOnlyNumbers( (1+2*4)/3) ) ? true ( (1+2*4)/3) ) contains '(' ? true int parentheses_begin = 0 int parentheses_end = 6 String ans = calc( 1+2*4 ) calc( 1+2*4 ) not hasOnlyNumbers( 1+2*4 ) ? true ( 1+2*4 ) contains '(' ? false ( 1+2*4 ) contains '^' ? false ( 1+2*4 ) contains 's' ? false ( 1+2*4 ) contains '*' ? true int opIndex = 3 int n1 = 2 int n2 = 4 String ans = n1 * n2 = 2 * 4 = 8 line = calc( 1+8 ) calc( 1+8 ) not hasOnlyNumbers( 1+8 ) ? true ( 1+8 ) contains '(' ? false ( 1+8 ) contains '^' ? false ( 1+8 ) contains 's' ? false ( 1+8 ) contains '*' ? false ( 1+8 ) contains '/' ? false ( 1+8 ) contains '+' ? true int opIndex = 1 int n1 = 1 int n2 = 8 String ans = n1 + n2 = 1 + 8 = 9 line = calc( 9 ) calc( 9 ) not hasOnlyNumbers( 9 ) ? false return 9 line = 9 not hasOnlyNumbers( 9 ) ? false return 9 line = 9 not hasOnlyNumbers( 9 ) ? false return 9 ans = 9 (9-1 >= 6+1) ? true line = 9/3 not hasOnlyNumbers( 9/3 ) ? true ( 9/3 ) contains '(' ? false ( 9/3 ) contains '^' ? false ( 9/3 ) contains 's' ? false ( 9/3 ) contains '*' ? false ( 9/3 ) contains '/' ? true int opIndex = 1 String n1 = 9 String n2 = 3 double ans = 9 / 3 = 3 line = calc( 3 ) calc( 3 ) not hasOnlyNumbers( 3 ) ? false return 3 line = 3 not hasOnlyNumbers( 3 ) ? false return 3
一些观察
- 不检查用户提供的输入是否有效
- 重要的是保持在 calc 方法中验证的运算顺序,以保持运算符之间的优先级(必须先进行求幂/除法,然后是乘法/除法,最后是加法/减法运算)
- 我的扫描仪有问题class,所以我使用 BufferedReader 读取输入
- 平方运算必须按如下方式进行:
s或 S
希望这对您有所帮助。如果你有什么不明白的地方,告诉我,我可以解释给你听。