繁体   English   中英

计算数组元素的出现次数 - 索引超出范围错误但索引号和超出范围长度是相同的数字?

[英]Counting occurrences of an array element - Index out of bounds error but the index number and out of bounds length are the same number?

所以我在为作业编写的代码方面遇到了一些问题,这让我发疯了。 这是我的第一个学期,我以前从未编写过代码,所以我知道我还有很多东西要学。 无论如何,问题:

我有两个可能相关的问题,但我不是 100% 确定。 我收到此错误:

'线程“主”java.lang.ArrayIndexOutOfBoundsException 中的异常:索引 125 超出长度 125 的范围。

这指向以下代码部分(在特定行上注释):

public static String gradesDistn() {
    String gradeDistn = "0";
    
    //Sort the above letterGrade array
    Arrays.sort(letterGrade);
    
    //This loop counts each occurrence of an element in the letterGrade array.
    for (int i = 0; i < letterGrade.length - 1; i++) {
        int count = 0;
        for(int j = i + 1; j < letterGrade.length; j++) {
            if  (letterGrade[i] == letterGrade[j]) 
                count++;
                
        System.out.println (gradeDistn = letterGrade[i] + ": " + count); //THIS IS THE ERROR LINE.
        i += (count-1);
        }
    }  
    return gradeDistn;

如果需要额外的上下文,我可以发布完整的代码。 本质上,我正在尝试计算存储在数组中的每个字母等级(A、B、C、D、E 和 F)的出现次数。 每次出现都基于另一个数组,该数组存储数字标记并随机生成。 所以结果应该是这样的:

答:6

乙:10

C:20

D:9

E:3

女:1

相反,我得到(从控制台复制):

答:1

A2

答:3

答:4

乙:5

乙:6

乙:7

乙:8

乙:9

乙:10

乙:11

C:11

C:11

D: 11

D: 11

女:11

C:20

D:9

E:3

女:1

我花了很长时间查看这些代码并试图让它工作,我觉得我对它潜在的明显问题视而不见。 对于这两个问题的任何帮助将不胜感激!

另请注意:分配需要一堆超级特定的方法,例如不能更改,不能使用附加类等。

对于这个答案,我将抛开ArrayIndexOutOfBoundsException的问题,提供有关如何生成频率分布的指导。

我的目标是拥有一系列计数器。 每个计数器将代表一个值或值范围。

对于这个例子,我想分析每天的高温。 我决定按 10 华氏度分组。 我可以决定 5 度、7 度或其他一些间隔。 它甚至可以是不规则的间隔。 但是,保持规律并以 10 度角使示例更易于理解。

确定按 10 度分组后,我接下来要确定最大值和最小值。 我会选择 -19 作为最冷,119 作为最热。 但是,我想允许超出该范围的事件。 所以,为了保持计数,我需要一个由 15 个计数器组成的数组。

接下来,我需要一种将温度测量“转换”为数组索引的方法。 我在下面的代码中使用了int变量k 为了更容易理解,我将计算分成 4 行,然后将结果用作下标:

public static int [] tempFreqDist (WeatherStats [] daily) {
    int [] count = new int [15];  // java initializes to zeros
    int k;
    for (int dIdx = 0; dIdx < daily.length; ++ dIdx) {
          k = daily [dIdx].getHighTemp();
          k = Math.max (k,-20);
          k = Math.min (k,120);
          k = k/10 + 2;
          count [k]++;
    }    
    return count;
}

我们希望将 -20 和更冷的温度组合在一起,无论低于 -20 多远。 所以,我们使用Math.max 同样,我们使用Math.min对 120 和更高的温度进行分组。 接下来,除以我们的分组因子,并调整结果,使最低的下标值为0

因此,结果是count的元素对应于温度范围:0 ➔ -20 和更冷; 1 ➔ “青少年”(10 至 19 岁)低于零; 2 ➔ 低于零的个位数; 3 ➔ 上面的零和个位数; 4 ➔ 零以上的青少年; 5 ➔ 20 岁,...,14 ➔ 100 岁以上的青少年; 14 ➔ 120 及以上。

但是,假设类别的“宽度”是不规则的? 一种可能性是您可以使用if... else链:

int t = daily [dIdx].getHighTemp();
if (t <= -20) k = 0;
else if (t <= -13) k = 1;
else if (t <= 0) k = 2;
else if (t <= 15) k = 3;
else if (t <= 28) k = 4;

等等。

if... else链可用于字母等级:

 public int[] gradeFD (char [] letterGrade) {
    int [] count = new int [6]; 
      // 0 ➔ A, 1 ➔ B, 2 ➔ C, 3 ➔ D, 4 ➔ E, 5 ➔ F 
    ...
    for (int m = 0; m < letterGrade.length; ++m) {
       if (letterGrade[m] == 'A') count[0]++;
       else if (letterGrade[m] == 'B) count [1]++;
       else if ... 

但是,对于字母等级之类的东西,我更喜欢switchif... else链:

public static int [] gradeFD (char [] letterGrade) {
    int [] count = new int [6];
    for (int m = 0; m < letterGrade.length; ++m) {
        switch (letterGrade [m]) {
            case 'A': 
                count[0]++;
                break;
            case 'B':
                count [1]++;
                break;
            case 'C':
                count [2]++;
                break;
            case 'D':
                count [3]++;
                break;
... 

您可以使用一个“技巧”轻松将字母转换为索引。 回想一下, char本质上是一个 integer 原语:您可以对其进行数值计算。

 char letter;
 int idx;
 ...
 if (letter >= 'A' && letter <= 'Z') { 
    idx = letter - 'A'; // result is zero to 25
 ... 

这利用了字母 A 到 Z 在字符集编码中是连续的这一事实。 然而,这并不普遍。 例如,EBCDIC 在IJ之间以及RS 、 IIRC 之间具有非字母字符。

Simple Technic if you understand this, you can solve so many problems with this method. Creating a other array with the same size of user giving Array    
     {
                  int[] a = { 1, 2, 3, 4, 5, 1, 2, 3, 7, 8 };
                  //create a Array with of a[]
                  int[] b = new int[a.length];

                  for (int i = 0; i < a.length; i++) {
                        //set count =1 in every new array element taken.
                        int count = 1;
                        for (int j = i + 1; j < a.length; j++) {
                              if (a[i] == a[j]) {
                                    count++;
                                    
                                    b[j] = -1;

                              }
                              
                              if (b[i] != -1) {
                                    //put count value into Second Array if its not -1;
                                    b[i] = count;
                              }
                        }
                  }
                  for (int i = 0; i < a.length; i++) {
                        if (b[i] != -1) {
                              System.out.println(a[i] + " " + b[i]);
                        }
                  }

            }
      }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM