问题描述
我已经在下面编写了代码,并附加了注释。该应用程序将读取用户输入的七个整数。然后,应用程序将打印出七个值中每个值的出现次数。
当我输入整数1 2 3 1 2 3 100
Error: Exception in thread "main" `java.lang.Arrayindexoutofboundsexception: 100` at u7a1_numofoccurrinsevenints.U7A1_NumOfOccurrInSevenInts.main(U7A1_NumOfOccurrInSevenInts.java:78)
/Users/davramirez/Library/Caches/NetBeans/8.2/executor-snippets/run.xml:53: Java returned: 1
BUILD Failed (total time: 5 seconds)
我尝试在代码中使用Integer.MAX_VALU
E来解决此问题。我知道我的数组应该有7个而不是100个。输入应该不会影响程序。我感到难过。代码如下:
package u7a1_numofoccurrinsevenints;
// Initialize scanner untility
import java.util.Scanner;
/**
*
* @author davramirez
*/
public class U7A1_NumOfOccurrInSevenInts {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// Todo code application logic here
/**
* Call scanner method to take user input.
* Print out student copy.
* Print out instructions to enter seven numbers
*/
System.out.println("Student's copy");
Scanner input = new Scanner(system.in);
System.out.println("Enter seven numbers: ");
/**
* Initialize arrays number and count
* Array number takes integer value from user.
* Array count servers as counter in the program
* Declare variable counter as integer.
* Counter serves as counter in for loop to stop at 7
*/
int [] number = new int[7];
int [] count = new int[7];
int counter = 0;
/**
* Declare variable i as integer
* Declare variable tempHold as the integer with value of zero
* Variable tempHold temporarily stores value
* of the array number at a specific index
*/
int i,tempHold = 0;
/**
* For loop that populates array number from user input
* Counter++ used to count seven values of the array
* If statement that loops for counter to reach seven
* When seven reach the program exits
* stores user input to number[] array
*/
for(i=0; i < number.length; i++){
number[i] = input.nextInt();
counter++;
if(counter == 7){
break;
}
} // End of for loop
/**
* For loop that passes value of array
* The value is stored in the tempHold variable
* tempHold variable used as index value
* Count array tracks total occurrences of each integer.
*/
for(i = 0; i < number.length; i++){
tempHold = number[i];
count[tempHold]++;
}// End of for looop
/**
* For loop prints out number plus the occurrence
* If statement that checks with the integer is repeated
* If the does not repeat the program prints time occurred
* Else it uses times. This prints out grammatically correct results.
*/
for(i=1; i < count.length; i++){
if(count[i] > 0 && count[i] == 1){
System.out.printf("Number %d occurs %d time.\n",i,count[i]);
}
else if(count[i] >=2){
System.out.printf("Number %d occurs %d times.\n",count[i]);
}
}//end of for loop
}
}
解决方法
您可以使用 HashMap
package u7a1_numofoccurrinsevenints;
import java.util.HashMap;
import java.util.Scanner;
public class U7A1_NumOfOccurrInSevenInts {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] inputArray = new int[7];
System.out.print("Enter seven numbers: ");
for (int i = 0; i < 7; i++) {
inputArray[i] = input.nextInt();
}
HashMap<Integer,Integer> numberCountMap = new HashMap<>();
for(int element : inputArray){
numberCountMap.put(element,(numberCountMap.containsKey(element)) ? numberCountMap.get(element) + 1 : 1);
}
numberCountMap.forEach((key,value) -> System.out.println("Number " + key + " occurs " + value + " times."));
}
}
,
好吧,发生问题是因为您试图访问nil
数组中的索引100
,数组的大小仅为count[]
。
因此,此行是错误的:7
。
总的来说,您的方法过于复杂,无法解决。 更好和更清洁的方法已在该网站上发布了数千次,因此,在这里我不会为您的问题发布详细的代码段。但是您可以查看this solution,其中也包含说明。
编辑:
显然,您基本上只是拿了this response from a previous quesiton并稍加修改了。如果您进一步向下滚动,则会找到更合适的答案。
,您的讲师是否提到了单一责任原则或测试驱动的开发?与其他人讨论这项工作一样好。
您的main()
做得太多:将用户输入的内容扩展到一个数组中,处理该数组并报告结果。我建议您至少创建一个单独的“方法”,该函数接受一个整数数组并计算该数组中数字的出现次数。
我看到您正在使用NetBeans。明智的选择。这意味着您可以访问JUnit和TestNG。您可以使用这些测试框架之一来帮助您使程序更模块化,更易于测试。这也意味着在出现问题时更容易查明问题的根源。
采用Trushit的想法使用HashMap<Integer,Integer>
,为接受整数数组并返回HashMap<Integer,Integer>
的函数创建存根。
// STUB TO FAIL THE FIRST TEST
static HashMap<Integer,Integer> countOccur(int[] numbers) {
HashMap<Integer,Integer> map = new HashMap<>();
map.put(0,0);
return map;
}
接下来,将鼠标放在声明类(“ public class U7A1_NumOfOccurrInSevenInts
”)的行上,然后单击替换行号的灯泡。选择选项以创建新的JUnit测试类。
有时候,NetBeans会提供良好的测试,有时却没有。但是,如果没有警告,您可以暂时忽略这些测试。在测试类中,添加以下测试:
@Test
public void testAllNumbersTheSame() {
int[] numbers = {10,10,10};
HashMap<Integer,Integer> expected = new HashMap<>();
expected.put(10,7); // Ten occurs seven times
HashMap<Integer,Integer> actual = countOccur(numbers);
assertEquals(expected,actual);
}
(您可能需要为countOccur()
使用全限定名或添加静态导入)
运行测试(运行>测试文件)或使用键盘快捷键(在Windows上为Ctrl-F6)。该测试应该失败。只需对countOccur()
进行简单更改即可使其通过:
map.put(10,7);
现在写,期望得到不同的结果。要使用您的示例,
@Test
public void testDifferentNumbers() {
int[] numbers = {1,2,3,1,100};
HashMap<Integer,Integer> expected = new HashMap<>();
expected.put(1,2);
expected.put(2,2);
expected.put(3,2);
expected.put(100,1);
HashMap<Integer,actual);
}
当然,此测试将失败(先前的测试应仍通过)。请参阅Trushit的答案,以获得使其通过的一种可能方式(需要Java 8或更高版本)。