【问题标题】:Finding max values of array 12 elements at a time一次查找数组 12 个元素的最大值
【发布时间】:2017-05-11 12:28:27
【问题描述】:

我有一个包含大约 1000 个条目的数组,这些条目每年分为 12 个条目,我试图找到每年的最大值,为此我需要一次读取 12 个值并找到取这 12 个值的最大值,然后从数组中移至接下来的 12 个值,以此类推,直到完成。

为了做到这一点,我制作了一个临时数组来存储 12 个值,以及具有每年最高分数的最终数组。下面的代码不起作用,我不确定为什么,我花了很长时间研究和尝试不同的解决方案,任何帮助将不胜感激:)

//double rain[]= new double [1268];  this is the array declared earlier with data in

double maxRAINyear[]= new double [1200];
double temp [] = new double [12];
int arrayCounter = 0;
int count = 0;
for (int c = 36; c < rain.length; c++) {
   temp[count] = rain[c];
   if (count == 12){
       Arrays.sort(temp);
       double max = temp[temp.length - 1];
       maxRAINyear[arrayCounter] = max;
       arrayCounter++;
       count = 0;
   }
   count++;

}

【问题讨论】:

  • C 的 36 值是从哪里来的?
  • 打错了,应该是12,36的值是因为前36个值都是0,这部分程序不需要。
  • 在什么情况下不起作用?它会抛出异常还是产生不正确的输出?
  • 使用HashMap&lt;Integer, ArrayList&lt;Double&gt;&gt; 会不会更高效?通过这种方式,您可以将每月的降雨量按年份分开,并直接寻址每年的 ArrayList,您的代码将比您向我们展示的更容易阅读。
  • 1268 个月,也就是 210 年 8 个月?只是检查。

标签: java arrays sorting max


【解决方案1】:

在不知道代码产生什么的情况下很难看出代码有什么问题,但无论如何这都不是一个好方法。

我假设您受限于一个长数组的输入格式,即使多维数组可能更有意义,具体取决于它的其他用途。

// double rain[] = new double[1268]; // input
double maxRAINyear[] = new double[(rain.length+11) / 12];
double max = Double.NEGATIVE_INFINITY;
for (int i = 0; i < rain.length; i++)
{
    if (rain[i] > max) max = rain[i];
    if (i % 12 == 0)
    {
        maxRAINyear[i / 12] = max;
        max = Double.NEGATIVE_INFINITY;
    }
}
if (rain.length % 12 != 0) maxRAINyear[maxRAINyear.length-1] = max;

这会计算每 12 个数字的最大值,而不是单独存储它们并对其进行排序。我假设存储了整年。如果您想在最后考虑部分年份,则需要对其进行修改。

【讨论】:

  • 它确实在部分年份结束,准确地说是在第 5 个月,我将如何解释这一点?
  • 取决于你想用它做什么。因为我认为部分年份只是被忽略了。如果您想从中获取最大值,那么在这种情况下,您需要将数组长度增加一,然后在循环结束后将 max 的值放入最后一个槽中。
  • 您可以添加一个特殊情况,其中 if(i == rain.length -1 && i%12 != 0) 您执行 maxRAINyear[i/12+1] = max
  • 我已经编辑包含这个。我不想在循环中做额外的检查,而是在之后添加它,因为它对我来说看起来更整洁,但你可以在循环中做。
  • 这个输出有点偏,前 3 个最大值的预期输出是 119.1、156.7、112.6。实际输出是; 123.9,149.9 和 145.8
【解决方案2】:

我在没有临时数组的情况下实现了它,而是通过迭代数组来实现它。那应该更有效率。

    int amountOfYears = rain.length/12-3;
    double maxRAINyear[]= new double [amountOfYears];
    for(int i=0;i<amountOfYears;i++){

        //Find maximum for these 12 indixes
        double max = Double.NEGATIVE_INFINITY;
        for(int j=12*i+36;j<12*(i+1)+36;j++){ //use 12*i as an offset, that way, you don't need a temp array
            if(rain[j] > max)
                max = rain[j];
        }
        //store maximum
        maxRAINyear[i] = max;

    }

如果您还需要查找部分年份,请使用此

    int amountOfYears = Math.ceil(rain.length/12f)-3;
    double maxRAINyear[]= new double [amountOfYears];
    for(int i=0;i<amountOfYears;i++){

        //Find maximum for these 12 indixes
        double max = Double.NEGATIVE_INFINITY;
        int start = 12*i+36;
        int end = Math.min(rain.length,12*(i+1)+36);
        for(int j=start;j<end;j++){ //use 12*i as an offset, that way, you don't need a temp array
            if(rain[j] > max)
                max = rain[j];
        }
        //store maximum
        maxRAINyear[i] = max;

    }

【讨论】:

  • 那不必要的复杂 ;) 见gandaliter answer
  • @Jamie 实现过于复杂
  • 另外,我不认为你会在最后得到部分年份
  • @gandaliter 因为int amountOfYears = rain.length/12-3;,它会丢失除法的小数部分(部分年份)。
  • 啊,好吧,你将如何调整它以找到最小值?
【解决方案3】:

count 为11 时,您将其增加到12 并进入下一轮循环。现在temp[count] = rain[c]; 将尝试将值存储到temp 的索引12 中,但只有12 个索引为0 到11 的条目。所以我怀疑你得到的是ArrayIndexOutOfBoundsException

我认为您应该在 if 语句之前移动 count++。这样一来,12 的计数将在造成任何破坏之前重置为 0。

【讨论】:

    【解决方案4】:

    如果数组长度不是范围的倍数而无需进行多次检查,则此解决方案具有工作优势。

    public static double[] read(double[] array, int range) { 
        double[] result = new double[array.length / range + (array.length % range > 0 ? 1 : 0 )]; //Just add one cell if the length is not a multiple of the range
    
    
        double max = array[0];
        int i = 1;
        while (i < array.length) {
            if (i % range == 0) { //Next range
                result[i / range - 1] = max; //Save last
                max = array[i]; //Get current
            } else if (array[i] > max) {
                max = array[i];
            }
            ++i;
        }
        result[result.length - 1] = max; //for the last range
        return result;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-21
      • 2018-05-21
      • 2017-01-17
      • 2022-12-31
      • 2019-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多