【问题标题】:Count Occurrences of Seven Integers in Array计算数组中七个整数的出现次数
【发布时间】:2020-10-14 06:21:41
【问题描述】:

我已经编写了下面的代码,并且附加了 cmets。该应用程序将读取用户输入的七个整数。然后应用程序打印出这七个值中每一个的出现次数。

当我输入整数时程序崩溃: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_VALUE 来解决问题。我知道我的数组应该有 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",i, count[i]);
            }
         }//end of for loop
    
    } 
}

【问题讨论】:

  • 你的逻辑在这里失败 tempHold = number[i];计数[温度保持]++;您将数组值作为索引。这意味着如果您要添加一个大于 7 的数字。您的代码将给出您现在得到的异常。

标签: java arrays loops findbugs find-occurrences


【解决方案1】:

您可以通过使用 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."));
    }
}

【讨论】:

  • 谢谢。这段代码简洁明了。我将复习以了解 HashMap 方法。
【解决方案2】:

好吧,您的问题出现是因为您试图访问您的count[] 数组中的索引100,该数组的大小仅为7。 所以,这条线有问题:count[tempHold]++;

总而言之,您的方法过于复杂,无法奏效。 更好和更清洁的方法已经在这个网站上发布了数千次,所以我不会在这里为你的问题发布详细的 sn-p。不过你可以看看this solution,里面也有解释。

编辑:

显然,您基本上只是采用了this response from a previous quesiton 并稍作修改。如果您进一步向下滚动,您也会找到更合适的答案。

【讨论】:

  • 谢谢。我确实看了一下,看来使用 HashMap 是要走的路。
【解决方案3】:

您的讲师是否提到过单一职责原则或测试驱动开发?这项任务是讨论这些问题的好时机。

您的main() 做得太多:将用户的输入引导到一个数组中,处理该数组并报告结果。我建议您至少创建一个单独的“方法”,这是一个接收整数数组并计算该数组中数字出现次数的函数。

我看到您正在使用 NetBeans。明智的选择。这意味着您可以访问 JUnit 和 TestNG。您可以使用其中一种测试框架来帮助您使您的程序更加模块化并且更易于测试。这也意味着当出现问题时更容易查明问题的根源。

按照 Trushit 的想法使用 HashMap&lt;Integer, Integer&gt;,为一个函数创建一个存根,该函数接受一个整数数组并返回一个 HashMap&lt;Integer, Integer&gt;

    // 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, 10, 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, 2, 3, 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, Integer> actual = countOccur(numbers);
        assertEquals(expected, actual);
    }

这个测试当然会失败(之前的测试应该仍然通过)。有关使其通过的一种可能方法,请参阅 Trushit 的回答(需要 Java 8 或更高版本)。

【讨论】:

  • 感谢您的详细解释。使用单独的方法是我一直在寻找更有效地使用的方法。我会花时间回顾一下,并将其应用到我现在的工作中,随着课程的到来。再次感谢您。
  • 如果您遇到任何特定于 NetBeans 的问题,可以使用 NetBeans 邮件列表和 Slack 频道。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-18
  • 1970-01-01
  • 1970-01-01
  • 2016-03-19
相关资源
最近更新 更多