【问题标题】:How to exclude numbers from array sum/average/min/max?如何从数组总和/平均值/最小值/最大值中排除数字?
【发布时间】:2018-10-02 19:55:48
【问题描述】:

我正在为课堂作业做作业,我试图弄清楚如何获取数组中数字的平均值,同时排除数字 -999(用于表示缺失数据)我已经弄清楚如何得到总和/平均值/最小值/最大值等等,但我不知道如何从搜索范围中排除 -999。您可以在前几种方法中看到我迄今为止尝试解决的一些问题。我什至在谷歌上找不到任何可以开始解释我现在应该做什么的东西。 这些是我正在遵循的说明,以下是我当前的代码,感谢您提供的任何输入。

    /**
 * WeatherComputation.java
 */

//Put any imports below this line.
import java.util.*;

/**
 * Static methods library which compute averages and other
 * computations on integer arrays of temperatures.
 * 
 * @author Joel Swanson 
 * @version 03.29.2014
 */
public class WeatherComputation
{    
    /**
     * Average an array of temperatures.
     * @param temperatures An array storing temperatures as ints.
     * @return Returns the average of the array of ints.
     */
    public static double averageTemperature(int[] temperatures)
    {   
        int sum = 0;
        for (int i = 0; i < temperatures.length; i++)
        {
         sum += temperatures[i];
        }
        double average = sum / temperatures.length;
        return average;
    }

    /**
     * Find the highest in an array of temperatures.
     * @param temperatures An array storing temperatures as ints.
     * @return The largest value from the the array of ints.
     */
    public static int highestTemperature(int[] temperatures)
    {      
        int max = temperatures[0]; 
        for (int i = 1; i < temperatures.length; i++)
        {
            if(temperatures[i] > max)
            { 
                max = temperatures[i]; 
            } 
        }
        return max;
    } 

    /**
     * Find the lowest in an array of temperatures.
     * @param temperatures An array storing temperatures as ints.
     * @return The lowest value from the the array of ints.
     */
    public static int lowestTemperature(int[] temperatures)
    {
        int min = 0; 
        Arrays.sort(temperatures);

        while (true)
        {
            if (min == -999)
            {
                break;   
            }

            if(min > -999)
            {
                min = temperatures[0];
            }
        }

        for (int i = 1; i < temperatures.length; i++)
        {
            if (min < -999)
            {
                if (temperatures[i] < min)
                {
                    min = temperatures[i];   
                }    
            }
        } 

        return min;
    }

    /**
     * Return the total number of missing days.  That is days with
     * -999 recorded as the temperatures.
     * @param temperatures An array storing temperatures as ints.
     * @return The number of -999s found.
     */
    public static int numberMissing(int[] temperatures)
    {       
        int count = 0; 

        return count;
    } 

    /**
     * Calculate heating degree day.
     * @param max The highest temperature for a given day.
     * @param min The lowest temperature for a given day.
     * @return heating degree day data for this day.
     */
    public static double hdd(int max, int min)
    {
        double hdd = 0.0;

        return hdd;
    }

    /**
     * Calculate cooling degree day.
     * @param max The highest temperature for a given day.
     * @param min The lowest temperature for a given day.
     * @return cooling degree day data for this day.
     */
    public static double cdd(int max, int min)
    {
        double cdd = 0.0;

        return cdd;
    }    

    /**
     * Sum monthly heating degree days.
     * @param max An array with the highest temperatures for each day
     * in a given month.
     * @param min An array with the lowest temperatures for each day
     * in a given month.
     * @return The sum of the heating degree days.
     */
    public static double monthHdd(int[] max, int[] min)
    {
        double sum = 0.0;

        return sum;        
    }

    /**
     * Sum monthly cooling degree days.
     * @param max An array with the highest temperatures for each day
     * in a given month.
     * @param min An array with the lowest temperatures for each day
     * in a given month.
     * @return The sum of the cooling degree days.
     */
    public static double monthCdd(int[] max, int[] min)
    {
        double sum = 0.0;

        return sum;        
    }     
}

【问题讨论】:

  • 你的问题到底是什么?

标签: java arrays


【解决方案1】:

您确实想为此使用 Java 8 的流操作符。如果我采用您的代码,并省略了未实现的方法,并且没有描述实际计算的内容,我会得到:

/**
 * WeatherComputation.java
 */
import java.util.*;
import java.util.stream.IntStream;

/**
 * Static methods library which compute averages and other
 * computations on integer arrays of temperatures.
 *
 * @author Joel Swanson
 * @version 03.29.2014
 */
public class WeatherComputation {

    /**
     * Filters out all missing values (represented by -999).
     *
     * @param temperaturs an array storing temperatures as ints.
     * @return the list with the missing values removed
     */
    private static IntStream getFilteredArray(final int[] temperaturs) {
        return IntStream.of(temperaturs)
                .filter(i -> i != -999);
    }

    /**
     * Average an array of temperatures.
     *
     * @param temperatures an array storing temperatures as ints.
     * @return the average of the array of ints.
     */
    public static double averageTemperature(int[] temperatures) {
        // Returns 0 on an empty list. Your code will throw an exception
        return getFilteredArray(temperatures).average().orElse(0d);
    }

    /**
     * Find the highest in an array of temperatures.
     *
     * @param temperatures an array storing temperatures as ints.
     * @return the largest value from the the array of ints.
     */
    public static int highestTemperature(int[] temperatures) {
        return getFilteredArray(temperatures).max().orElse(0);
    }

    /**
     * Find the lowest in an array of temperatures.
     *
     * @param temperatures an array storing temperatures as ints.
     * @return the lowest value from the the array of ints.
     */
    public static int lowestTemperature(int[] temperatures) {
        return getFilteredArray(temperatures).min().orElse(0);
    }

    /**
     * Return the total number of missing days. That is days with
     * -999 recorded as the temperatures.
     *
     * @param temperatures an array storing temperatures as ints.
     * @return the number of -999s found.
     */
    public static int numberMissing(int[] temperatures) {
        return (int) IntStream.of(temperatures)
                .filter(t -> t == -999)
                .count();
    }
}

getFilteredArray 方法完成了所有工作。它将数组转换为IntStream,删除所有-999 值,并返回流。然后,您可以使用流运算符来计算平均值、总和、最小值、最大值等。

【讨论】:

  • OP看起来像个初学者,你不觉得他的老师会看穿吗?
  • 我不知道。我假设他的老师也知道 StackExchange。由 OP 决定是否以及如何将我的帖子包含在他的任务中。而且,他还需要自己实现一半的代码。但由于他是初学者,更有理由从一开始就学习正确的方法,即使用现有的库。
  • private static IntStream getFilteredArray(...) - 命名方法 getFilteredArray,但返回 IntStream 有点误导。
  • 好点。 getFilteredArrayAsStream 可能是一个更好的名字。
【解决方案2】:
public static double averageTemperature(int[] temperatures)
    {   
        int sum = 0;
        int count = 0;// number of valid values
        for (int i = 0; i < temperatures.length; i++)
        {
            if(temperatures[i] > -999){ // before calculating check value
                  count ++;
                  sum += temperatures[i];
             }
        }
        double average = count != 0 ? sum / count : -999 - 1; // preventing divide by zero
        return average;
    }

public static int lowestTemperature(int[] temperatures) {
    if(temperatures == null || temperatures.length == 0)
        return -999 - 1;
    int min = temperatures[0];
    for (int temperature : temperatures) {
        if (temperature > -999 && temperature < min) {
            min = temperature;
        }
    }
    return min;
}

【讨论】:

    【解决方案3】:

    对于最低温度,我会这样做:

    public static int lowestTemperature(int[] temperatures) {
        int min = 999;
        for (int temperature : temperatures) {
            if (temperature > -999 && temperature < min) {
                min = temperature;
            }
        }
        return min;
    }
    

    假设您的 WeatherComputation 类也会像考虑 -999(无效值)一样考虑 999。原因很简单,如果一个月内只有负值怎么办?那么,您的int min = 0 将不正确。

    至于平均温度:

    public static double averageTemperature(int[] temperatures) {
        int sum = 0, validTemperatureCounter = 0;
        for (int temperature : temperatures) {
            if (temperature > -999 && temperature < 999) {
                validTemperatureCounter++;
                sum += temperature;
            }
        }
        return sum / (double)validTemperatureCounter;
    }
    

    我还冒昧地忽略了999 的值。

    更新

    为了好玩,一个班轮:

    public static double averageTemperatureOneLiner(int[] temperatures) {
        return Arrays.stream(temperatures).filter(t -> t > -999 && t < 999).average().orElse(0);
    }
    
    
    public static int lowestTemperatureOneLiner(int[] temperatures) {
        return Arrays.stream(temperatures).filter(t -> t > -999 && t < 999).min().orElse(0);
    }
    
    
    public static int highestTemperatureOneLiner(int[] temperatures) {
        return Arrays.stream(temperatures).filter(t -> t > -999 && t < 999).max().orElse(0);
    }
    

    【讨论】:

    • int min = 999; - 如果最低温度是1000 怎么办? int min = Integer.MAX_VALUE; 会更好。
    • @Turing85 好点,我也考虑过这样做,但是由于练习指定我们应该忽略-999 下的值,我假设我们也会忽略999 及以上的值以保持一致性。由于所有高于和低于 999 和 -999 的值都将被忽略,所以只要它在这些范围之外,值是什么并不重要。更不用说,如果温度高于 999,那将是一个地狱般的天气
    • 据我所知,没有给出单位。也许它是以 Millicelsius 或 Millifahrenheit 给出的?至于你发布的文字......它只谈论-999的具体价值。尽管您的假设是合理的,但它不在规范范围内。也许有一个 -1000 的值,也许这应该被视为“一个真正的价值”(尽管我非常怀疑现实生活中的这种规范)。
    • @Turing85 类的名称是“WeatherComputation”,而不是“TemperatureComputation”,因此我们可以假设他在谈论天气。最高记录温度为 56.7 摄氏度(1913 年 7 月 10 日)guinnessworldrecords.com/world-records/…,但您是对的,我们不知道单位。如果 OP 更新,我会改变我的答案。
    【解决方案4】:

    您只需要在每个步骤中检查该值是否是排除的值,然后再在您的 sum/average/min/max 方法中使用它。

    例如:

    public static double averageTemperature(int[] temperatures) 
    {   
        int sum = 0;
        int count = 0;
        for (int i = 0; i < temperatures.length; i++) 
        {
           if (temperatures[i] != -999) {
               sum += temperatures[i];
               count++;
           }
        }
        double average = sum / count;
        return average;
    }
    

    【讨论】:

    • 在除以 count 之前,您可能需要检查它是否为 0。
    • OP 还可以通过将-999 提取为常量来进一步改进代码,因为它在文件中的多个位置使用(合并此答案后又出现一次)。
    • 这行不通,因为sumcount 是整数,所以它会取整平均值。您需要将sumcount 平均转换为doubledouble average = (double)sum / count;
    猜你喜欢
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 2014-06-11
    • 2013-04-01
    相关资源
    最近更新 更多