(Noob Coder) 基本计算器问题 + 代码建议
(Noob Coder) Basic Calculator Issue + Code Advice
我是一名学习者 Java,作为高中作业之外的个人项目,我决定制作一些数学解决方案以供练习。
为了热身,我决定编写一个基本的计算器程序...它可以工作...有点。所以...请帮助我!
目标:
-> 要有一个计算器,通过 Scanner 输入,可以使用运算符 [+、-、/、^(Math.pow)、*] 计算任何数字序列。 (例如:1+2+4+2 等)
什么有效:
-> 可以计算两个数的求和、乘积、幂、差和除法(int 或 double,但答案是 double)。
什么不起作用:
-> 它不能输入任何空格,否则会在第一个数组(总和)上出现 'out of bounds' 错误,依此类推
-> 它无法计算任何复合问题(例如:1+2+3、3*4^6 等)。
我计划为此添加许多其他内容(三角函数、额外的权力等),但就目前而言,这需要工作。有人可以告诉我如何解决这些问题吗?
最重要的是:
我应该注意哪些最大的编程错误(除了无法正常工作)(根据您看到的代码)?我通常按顺序和逻辑编程,但我觉得我(和我的代码)可以更有效率。
代码:
import java.util.*;
import java.io.*;
import java.lang.System;
import java.util.stream.*;
public class basicCalculator {
public static void main(String args[])throws IOException{
System.out.println("What would you like to calculate?");
Scanner inputNum = new Scanner(System.in);
String inputI = inputNum.nextLine();
Scanner inputScan = new Scanner(inputI);
Scanner inputScan2 = inputScan.useDelimiter("\+|\-|\/|\*|\^|\s");
Scanner inputScan3 = new Scanner(inputI);
double textContent[] = new double[1000];
int loopCount = -1;
int loopCount2 = 1;
int loopCount3 = 0;
double[] partOfResult = new double[1000];
while(inputScan.hasNextDouble()){
loopCount++;
textContent[loopCount] = inputScan.nextDouble();
}
while(inputScan3.hasNext()){
if(inputI.contains("+")){
partOfResult[loopCount3] = (textContent[loopCount2 - 1] + textContent[loopCount2]);
loopCount3++;
loopCount2++;
}else if(inputI.contains("-")){
partOfResult[loopCount3] = (textContent[loopCount2 - 1] - textContent[loopCount2]);
loopCount3++;
loopCount2++;
}
else if(inputI.contains("/")){
partOfResult[loopCount3] = (textContent[loopCount2 - 1] / textContent[loopCount2]);
loopCount3++;
loopCount2++;
}
else if(inputI.contains("*")){
partOfResult[loopCount3] = (textContent[loopCount2 - 1] * textContent[loopCount2]);
loopCount3++;
loopCount2++;
}
else if(inputI.contains("^")){
partOfResult[loopCount3] = (Math.pow(textContent[loopCount - 1], textContent[loopCount]));
loopCount3++;
loopCount2++;
}
if(inputScan.hasNext() == false){
double[] answer = new double[1000];
for(int i = 0; i <= loopCount3;){
answer[i] = partOfResult[i] + partOfResult[i+1];
i++;
}
double sum = DoubleStream.of(answer).sum();
System.out.println("The answer is " + sum);
break;
}
}
inputScan3.close();
inputScan2.close();
inputScan.close();
inputNum.close();
}
}
谢谢!
import java.lang.System;
这是不必要的。 java.lang
是在你不说的情况下导入的,所以你已经可以在你的代码中编写 System
而不用这一行。您可以安全地删除它。
Scanner inputScan2 = inputScan.useDelimiter("\+|\-|\/|\*|\^|\s");
只是因为 useDelimiter
returns a Scanner
并不意味着您需要将其放入变量中。你永远不会再使用 inputScan2
除非关闭它(并且在任何情况下,inputScan2
等于 inputScan
在这一行之后,使其变得多余。)所以我将缩短这一行:
inputScan.useDelimiter("\+|\-|\/|\*|\^|\s");
并删除关闭此未使用扫描仪的相应行。
将 loopCount2
和 loopCount3
作为单独的变量有点奇怪,因为它们总是彼此相距仅一。看来你可以摆脱其中之一。
我注意到你除了 main 方法之外没有任何方法。对于相对较小的程序来说,这还算不错,但最好养成将代码拆分为方法的习惯。
我注意到您没有任何代码注释。注释通常可以帮助您(和其他人)理解您的代码。特别是当变量被命名为 inputScan3
之类的东西时——这个名称给出了变量的一个非常笼统的概念,但它并没有真正说明为什么它与 inputScan
不同。评论会对此有所帮助。
像 if(inputI.contains("+")){
这样的行永远不会对复合语句有多大好处 - 你正在检查整个字符串是否包含 +
,如果你是processing 4+2*3
因为它不会告诉你当前是在做加法还是乘法。如果你想处理复合语句,你将不得不重做检查你正在执行的操作的方式。
我注意到您将 answer
数组的大小设置为 1000。这对于您的其他数组可能是可以理解的,因为您在创建它们时不知道它们的大小,但是对于这个数组,您已经知道尺寸 - 它是 loopCount3 + 1
。所以你可以写 double[] answer = new double[loopCount3+1];
并节省一些内存。
我会拆分代码。我看到一个 class 与输入一起工作, return 一个带有操作数和操作的对象,某种理解输入语法的智能堆栈。我看到一个 class 可以处理您堆叠的对象并可以调用所需操作的方法。
那你的 main 就是这样的
public static void main(String args[])throws IOException{
System.out.println("What would you like to calculate?");
Scanner inputNum = new Scanner(System.in);
OperationsStack operations = new OperationBuilder(inputNum).build();
Calculator calculator = new Calculator();
Double result = calculator.compute(operations);
System.out.println("The answer is " + result);
}
编辑:请参阅 polish notation 了解有关如何处理输入的一些想法。
我是一名学习者 Java,作为高中作业之外的个人项目,我决定制作一些数学解决方案以供练习。
为了热身,我决定编写一个基本的计算器程序...它可以工作...有点。所以...请帮助我!
目标:
-> 要有一个计算器,通过 Scanner 输入,可以使用运算符 [+、-、/、^(Math.pow)、*] 计算任何数字序列。 (例如:1+2+4+2 等)
什么有效:
-> 可以计算两个数的求和、乘积、幂、差和除法(int 或 double,但答案是 double)。
什么不起作用:
-> 它不能输入任何空格,否则会在第一个数组(总和)上出现 'out of bounds' 错误,依此类推
-> 它无法计算任何复合问题(例如:1+2+3、3*4^6 等)。
我计划为此添加许多其他内容(三角函数、额外的权力等),但就目前而言,这需要工作。有人可以告诉我如何解决这些问题吗?
最重要的是:
我应该注意哪些最大的编程错误(除了无法正常工作)(根据您看到的代码)?我通常按顺序和逻辑编程,但我觉得我(和我的代码)可以更有效率。
代码:
import java.util.*;
import java.io.*;
import java.lang.System;
import java.util.stream.*;
public class basicCalculator {
public static void main(String args[])throws IOException{
System.out.println("What would you like to calculate?");
Scanner inputNum = new Scanner(System.in);
String inputI = inputNum.nextLine();
Scanner inputScan = new Scanner(inputI);
Scanner inputScan2 = inputScan.useDelimiter("\+|\-|\/|\*|\^|\s");
Scanner inputScan3 = new Scanner(inputI);
double textContent[] = new double[1000];
int loopCount = -1;
int loopCount2 = 1;
int loopCount3 = 0;
double[] partOfResult = new double[1000];
while(inputScan.hasNextDouble()){
loopCount++;
textContent[loopCount] = inputScan.nextDouble();
}
while(inputScan3.hasNext()){
if(inputI.contains("+")){
partOfResult[loopCount3] = (textContent[loopCount2 - 1] + textContent[loopCount2]);
loopCount3++;
loopCount2++;
}else if(inputI.contains("-")){
partOfResult[loopCount3] = (textContent[loopCount2 - 1] - textContent[loopCount2]);
loopCount3++;
loopCount2++;
}
else if(inputI.contains("/")){
partOfResult[loopCount3] = (textContent[loopCount2 - 1] / textContent[loopCount2]);
loopCount3++;
loopCount2++;
}
else if(inputI.contains("*")){
partOfResult[loopCount3] = (textContent[loopCount2 - 1] * textContent[loopCount2]);
loopCount3++;
loopCount2++;
}
else if(inputI.contains("^")){
partOfResult[loopCount3] = (Math.pow(textContent[loopCount - 1], textContent[loopCount]));
loopCount3++;
loopCount2++;
}
if(inputScan.hasNext() == false){
double[] answer = new double[1000];
for(int i = 0; i <= loopCount3;){
answer[i] = partOfResult[i] + partOfResult[i+1];
i++;
}
double sum = DoubleStream.of(answer).sum();
System.out.println("The answer is " + sum);
break;
}
}
inputScan3.close();
inputScan2.close();
inputScan.close();
inputNum.close();
}
}
谢谢!
import java.lang.System;
这是不必要的。 java.lang
是在你不说的情况下导入的,所以你已经可以在你的代码中编写 System
而不用这一行。您可以安全地删除它。
Scanner inputScan2 = inputScan.useDelimiter("\+|\-|\/|\*|\^|\s");
只是因为 useDelimiter
returns a Scanner
并不意味着您需要将其放入变量中。你永远不会再使用 inputScan2
除非关闭它(并且在任何情况下,inputScan2
等于 inputScan
在这一行之后,使其变得多余。)所以我将缩短这一行:
inputScan.useDelimiter("\+|\-|\/|\*|\^|\s");
并删除关闭此未使用扫描仪的相应行。
将 loopCount2
和 loopCount3
作为单独的变量有点奇怪,因为它们总是彼此相距仅一。看来你可以摆脱其中之一。
我注意到你除了 main 方法之外没有任何方法。对于相对较小的程序来说,这还算不错,但最好养成将代码拆分为方法的习惯。
我注意到您没有任何代码注释。注释通常可以帮助您(和其他人)理解您的代码。特别是当变量被命名为 inputScan3
之类的东西时——这个名称给出了变量的一个非常笼统的概念,但它并没有真正说明为什么它与 inputScan
不同。评论会对此有所帮助。
像 if(inputI.contains("+")){
这样的行永远不会对复合语句有多大好处 - 你正在检查整个字符串是否包含 +
,如果你是processing 4+2*3
因为它不会告诉你当前是在做加法还是乘法。如果你想处理复合语句,你将不得不重做检查你正在执行的操作的方式。
我注意到您将 answer
数组的大小设置为 1000。这对于您的其他数组可能是可以理解的,因为您在创建它们时不知道它们的大小,但是对于这个数组,您已经知道尺寸 - 它是 loopCount3 + 1
。所以你可以写 double[] answer = new double[loopCount3+1];
并节省一些内存。
我会拆分代码。我看到一个 class 与输入一起工作, return 一个带有操作数和操作的对象,某种理解输入语法的智能堆栈。我看到一个 class 可以处理您堆叠的对象并可以调用所需操作的方法。
那你的 main 就是这样的
public static void main(String args[])throws IOException{
System.out.println("What would you like to calculate?");
Scanner inputNum = new Scanner(System.in);
OperationsStack operations = new OperationBuilder(inputNum).build();
Calculator calculator = new Calculator();
Double result = calculator.compute(operations);
System.out.println("The answer is " + result);
}
编辑:请参阅 polish notation 了解有关如何处理输入的一些想法。