Java 2数组min max avg?

时间:2022-09-28 10:25:02

How do I create a loop to generate min, max, avg for 2 array lists, i have only generated the min, max and avg with sum for single array lists so far.

如何创建一个循环来为2个数组列表生成min,max,avg,到目前为止,我只为单个数组列表生成了min,max和avg。

These are the 2 arrays User[] & Withdrawals[]:

这些是2个数组User []&Withdrawals []:

User, Withdrawals
1 , 90.00
2 , 85.00
4 , 75.00
5 , 65.00
2 , 40.00
1 , 80.00
3 , 50.00
5 , 85.00
4 , 80.00
1 , 70.00

size = 10

This is what i have tried, as i have no clue about 2 arrays interdependent:

这是我试过的,因为我不知道2个数组相互依赖:

double min = 0.0;
double max = 0.0;
double sum = 0.0;
double avg = 0.0;

for(int i = 0; i <size; i++){
.
.
for(int j = 0; j < Withdrawals.length; j++){
   if(Withdrawals[User[i]] > max){  
      max = Withdrawals[j];  
   }  
   if(Withdrawals[User[i]] < min){  
      min = Withdrawals[j];  
   }
}  
sum += Withdrawals[j];
avg = sum/size;
}

how do i print the min, max, avg from the no of withdrawals per user ? :S

如何从每个用户的提款数打印最小值,最大值,平均值? :S

I have already counted the number of withdrawals per user.

我已经计算了每位用户的提款次数。

Conditions are: create everything from scratch instead of using available library features of Java.

条件是:从头开始创建所有内容,而不是使用Java的可用库功能。

4 个解决方案

#1


0  

Divide and conquer :) Yes, I know that is a term used for an algorithm technique, in this case what I mean is... work with small parts.

划分和征服:)是的,我知道这是一个用于算法技术的术语,在这种情况下我的意思是......使用小部件。

First having the min, max, avg for a simple array:

首先得到一个简单数组的min,max,avg:

double[] values = {2,3,4,5,6,7};

double min = values[0];
double max = values[0];
double sum = 0;

for (double value : values) {
     min = Math.min(value, min);
     max = Math.max(value, max);
     sum += value;
}

double avg = sum / values.length;

System.out.println("Min: " + min);
System.out.println("Max: " + max);
System.out.println("Avg: " + avg);

Note: Since you can't use Java libraries for your assignment, is easy to do your own versions of the min/max functions (read the Math JavaDoc)

注意:由于您无法使用Java库进行分配,因此很容易使用自己的min / max函数版本(请阅读Math JavaDoc)

Now you can encapsulate this code in a function, you can start by returning another array:

现在您可以将此代码封装在一个函数中,您可以从返回另一个数组开始:

static double[] minMaxAvg(double[] values) {
    double min = values[0];
    double max = values[0];
    double sum = 0;

    for (double value : values) {
        min = Math.min(value, min);
        max = Math.max(value, max);
        sum += value;
    }

    double avg = sum / values.length;

    return new double[] {min, max, avg};
}

public static void main(String[] args) {
    double[] values = {2,3,4,5,6,7};
    double[] info = minMaxAvg(values);
    System.out.println("Min: " + info[0]);
    System.out.println("Max: " + info[1]);
    System.out.println("Avg: " + info[2]);
}

Using an array is a little bit ugly to read, so is better if you create a class to hold the min, max, avg. So lets refactor the code a little bit:

使用数组有点难看,所以如果你创建一个类来保持min,max,avg会更好。所以让我们稍微重构一下代码:

class ValueSummary {
    final double min;
    final double max;
    final double avg;

    static ValueSummary createFor(double[] values) {
        double min = values[0];
        double max = values[0];
        double sum = 0;

        for (double value : values) {
            min = Math.min(value, min);
            max = Math.max(value, max);
            sum += value;
        }

        double avg = sum / values.length;

        return new ValueSummary(min, max, avg);
    }

    ValueSummary(double min, double max, double avg) {
        this.min = min;
        this.max = max;
        this.avg = avg;
    }

    public String toString() {
        return "Min: " + min + "\nMax: " + max +"\nAvg: " + avg;
    }
}


public static void main(String[] args) {
    double[] values = {2,3,4,5,6,7};
    ValueSummary info = ValueSummary.createFor(values);
    System.out.println(info);
}

You don't specify it in your question, but I assume that you have an array for each user (maybe each withdrawals is another array). Now that you have the bottom parts, we can switch to a top-down thinking.

你没有在你的问题中指定它,但我假设你有一个每个用户的数组(也许每个提取是另一个数组)。现在您已经掌握了底部部分,我们可以切换到自上而下的思维。

So your code could be something like this:

所以你的代码可能是这样的:

for (User aUser : users) {
     System.out.println("User: " + aUser);
     System.out.println(ValueSummary.createFor(withdrawalsOf(aUser)));
}

Ok, but this is just the idea, you still have the problem to relate aUser with its withdrawals. You have several options here:

好的,但这只是想法,你仍然有问题将aUser与其提款联系起来。你有几个选择:

  1. Make a "table" User-> Withdrawals, that is what you are trying to do with the two arrays. The User index in the array acts like a "user id". When you learn about Map you will see that you can use a better representation for the index.
  2. 创建一个“表”User-> Withdrawals,这就是你要对两个数组做的事情。数组中的用户索引就像一个“用户ID”。当您了解Map时,您将看到可以使用更好的索引表示。

  3. Having a Map or array is just an optimization, of the relationship User->Withdrawls, but you can represent that relationship with an object (ie UserWithdrawls)
  4. 拥有一个Map或数组只是User-> Withdrawls关系的一个优化,但你可以表示与一个对象的关系(即UserWithdrawls)

Option 1:

static class User {
    final String name;
    public User(String s) { name = s; }
}
public static void main(String[] args) {
    User[] users = { new User("John"), new User("Doe")};
    double[][] withdrawals = {
         new double[] { 1, 2, 3}, new double[] { 10,22, 30} 
    };
    for (int i = 0; i < users.length; i++) {
        System.out.println("User: " + users[i].name);
        System.out.println(ValueSummary.createFor(withdrawals[i]));
    }
}

Option 2:

static class User {
    final String name;
    public User(String s) { name = s; }
}
static class UserWithdrawls {
    final User user;
    final double[] withdrawals;
    final ValueSummary summary;
    UserWithdrawls(User user, double[] withdrawals) {
        this.user = user;
        this.withdrawals = withdrawals;
        this.summary = ValueSummary.createFor(withdrawals);
    }
}
public static void main(String[] args) {
    UserWithdrawls[] userWithdrawls = {
            new UserWithdrawls(new User("John"), new double[] { 1, 2, 3}),
            new UserWithdrawls(new User("Doe"), new double[] { 10, 22, 30})
    };
    for (UserWithdrawls uw : userWithdrawls) {
        System.out.println("User: " + uw.user.name);
        System.out.println(uw.summary);
    }
}

Additional notes: If you are studying Computer Science, you'll learn in the future that the loop to calculate max, min, avg has a complexity of O(n). If the values array is fully loaded in memory, doing the max/min/avg in three different functions (thus reading the array 3 times) is still an algorithm of O(n) order with a bigger constant. With the power of today's computers the constant is so small, that most of the time you'll not get any gain from calculating min/max/avg in the same loop. In contrast you can gain code readability, for example in Groovy the minMaxAvg code could be written like this:

附加说明:如果您正在学习计算机科学,您将在未来学习计算max,min,avg的循环具有O(n)的复杂度。如果值数组在内存中完全加载,则在三个不同的函数中执行max / min / avg(因此读取数组3次)仍然是具有更大常量的O(n)阶的算法。凭借当今计算机的强大功能,常数非常小,大多数情况下,在同一循环中计算最小值/最大值/平均值时,您无法获得任何收益。相比之下,您可以获得代码可读性,例如在Groovy中,minMaxAvg代码可以像这样编写:

 def values = [2,3,4,5,6,7];
 println values.min()
 println values.max()
 println values.sum() / values.size()

#2


0  

Quick n Dirty: Use a second for loop for the second array, but do not reinitialize the min, max etc again.

Quick n Dirty:对第二个数组使用第二个for循环,但不要再次重新初始化min,max等。

Cleaner would be to make a class to hold the min, max etc, and a method that is passed this result object and an array. The method then scans the array and updates the result objects min, max etc. Call the method for each array.

Cleaner将创建一个类来保存min,max等,以及一个传递此结果对象和数组的方法。然后该方法扫描数组并更新结果对象min,max等。为每个数组调用方法。

#3


0  

Why don't you try to look at the code of Descriptive Statistics in the Commons Math library? Or better, use it instead of reinvent the wheel?

你为什么不试着在Commons Math库中查看描述性统计的代码?或者更好,使用它而不是重新发明*?

DescriptiveStatistics de = new DescriptiveStatistics();

de.addValue(..) // Your values
// Add more values

Double max = de.getMax();
Double min = de.getMin();
Double avg = de.getSum() / de.getN(); // or de.getMean();

And use an instance of DescriptiveStatistics for every array.

并为每个数组使用DescriptiveStatistics实例。

#4


0  

I think it would be better if you stored the details for each user in a seperate data structure like the following class named UserWithdrawals.

我认为如果将每个用户的详细信息存储在一个单独的数据结构中,如下面的名为UserWithdrawals的类,那会更好。

public class Program1{
    public static class UserWithdrawals{
        private LinkedList<Double> withdrawals=new LinkedList<>();

        public void add(Double amt){
            this.withdrawals.add(amt);
        }

        public Double getMinimum(){
            Double min=this.withdrawals.get(0);
            for(Double amt:this.withdrawals)
                if(amt.compareTo(min)<0) min=amt;
            return min;
        }

        public Double getMaximum(){
            Double max=this.withdrawals.get(0);
            for(Double amt:this.withdrawals)
                if(amt.compareTo(max)>0) max=amt;
            return max;
        }


        public Double getAverage(){
            Double sum=new Double(0);
            for(Double amt:this.withdrawals)
                sum+=amt;
            return sum/this.withdrawals.size();
            //this method will fail if the withdrawals list is updated during the iteration
        }

        /*You can also combine the three into a single method and return an array of Double object coz the iteration is same.*/

    }

    /*now you iterate over your two array lists (This wont work if the two array lists - 'Users' and 'Withdrawals' are of different size) and store the withdrawal data associated with a user in the corresponding map value - Maps or Associative arrays are a very basic data structure so your professor should not have any problems with this*/

    private HashMap<Integer,UserWithdrawals> withdrawals_map=new HashMap<>();

    public Program1(ArrayList<Integer> Users, ArrayList<Double> Withdrawals){
        for(int i=0;i<Users.size();i++){
            Integer user_no=Users.get(i);
            Double withdrawal_amt=Withdrawals.get(i);
            if(this.withdrawals_map.get(user_no)==null){
                this.withdrawals_map.put(user_no,new UserWithdrawals());
            }
            this.withdrawals_map.get(user_no).add(withdrawal_amt);
        }
    }

    public UserWithdrawals getUserWithdrawalsData(Integer user_no){
        return this.withdrawals_map.get(user_no);
    }
}

#1


0  

Divide and conquer :) Yes, I know that is a term used for an algorithm technique, in this case what I mean is... work with small parts.

划分和征服:)是的,我知道这是一个用于算法技术的术语,在这种情况下我的意思是......使用小部件。

First having the min, max, avg for a simple array:

首先得到一个简单数组的min,max,avg:

double[] values = {2,3,4,5,6,7};

double min = values[0];
double max = values[0];
double sum = 0;

for (double value : values) {
     min = Math.min(value, min);
     max = Math.max(value, max);
     sum += value;
}

double avg = sum / values.length;

System.out.println("Min: " + min);
System.out.println("Max: " + max);
System.out.println("Avg: " + avg);

Note: Since you can't use Java libraries for your assignment, is easy to do your own versions of the min/max functions (read the Math JavaDoc)

注意:由于您无法使用Java库进行分配,因此很容易使用自己的min / max函数版本(请阅读Math JavaDoc)

Now you can encapsulate this code in a function, you can start by returning another array:

现在您可以将此代码封装在一个函数中,您可以从返回另一个数组开始:

static double[] minMaxAvg(double[] values) {
    double min = values[0];
    double max = values[0];
    double sum = 0;

    for (double value : values) {
        min = Math.min(value, min);
        max = Math.max(value, max);
        sum += value;
    }

    double avg = sum / values.length;

    return new double[] {min, max, avg};
}

public static void main(String[] args) {
    double[] values = {2,3,4,5,6,7};
    double[] info = minMaxAvg(values);
    System.out.println("Min: " + info[0]);
    System.out.println("Max: " + info[1]);
    System.out.println("Avg: " + info[2]);
}

Using an array is a little bit ugly to read, so is better if you create a class to hold the min, max, avg. So lets refactor the code a little bit:

使用数组有点难看,所以如果你创建一个类来保持min,max,avg会更好。所以让我们稍微重构一下代码:

class ValueSummary {
    final double min;
    final double max;
    final double avg;

    static ValueSummary createFor(double[] values) {
        double min = values[0];
        double max = values[0];
        double sum = 0;

        for (double value : values) {
            min = Math.min(value, min);
            max = Math.max(value, max);
            sum += value;
        }

        double avg = sum / values.length;

        return new ValueSummary(min, max, avg);
    }

    ValueSummary(double min, double max, double avg) {
        this.min = min;
        this.max = max;
        this.avg = avg;
    }

    public String toString() {
        return "Min: " + min + "\nMax: " + max +"\nAvg: " + avg;
    }
}


public static void main(String[] args) {
    double[] values = {2,3,4,5,6,7};
    ValueSummary info = ValueSummary.createFor(values);
    System.out.println(info);
}

You don't specify it in your question, but I assume that you have an array for each user (maybe each withdrawals is another array). Now that you have the bottom parts, we can switch to a top-down thinking.

你没有在你的问题中指定它,但我假设你有一个每个用户的数组(也许每个提取是另一个数组)。现在您已经掌握了底部部分,我们可以切换到自上而下的思维。

So your code could be something like this:

所以你的代码可能是这样的:

for (User aUser : users) {
     System.out.println("User: " + aUser);
     System.out.println(ValueSummary.createFor(withdrawalsOf(aUser)));
}

Ok, but this is just the idea, you still have the problem to relate aUser with its withdrawals. You have several options here:

好的,但这只是想法,你仍然有问题将aUser与其提款联系起来。你有几个选择:

  1. Make a "table" User-> Withdrawals, that is what you are trying to do with the two arrays. The User index in the array acts like a "user id". When you learn about Map you will see that you can use a better representation for the index.
  2. 创建一个“表”User-> Withdrawals,这就是你要对两个数组做的事情。数组中的用户索引就像一个“用户ID”。当您了解Map时,您将看到可以使用更好的索引表示。

  3. Having a Map or array is just an optimization, of the relationship User->Withdrawls, but you can represent that relationship with an object (ie UserWithdrawls)
  4. 拥有一个Map或数组只是User-> Withdrawls关系的一个优化,但你可以表示与一个对象的关系(即UserWithdrawls)

Option 1:

static class User {
    final String name;
    public User(String s) { name = s; }
}
public static void main(String[] args) {
    User[] users = { new User("John"), new User("Doe")};
    double[][] withdrawals = {
         new double[] { 1, 2, 3}, new double[] { 10,22, 30} 
    };
    for (int i = 0; i < users.length; i++) {
        System.out.println("User: " + users[i].name);
        System.out.println(ValueSummary.createFor(withdrawals[i]));
    }
}

Option 2:

static class User {
    final String name;
    public User(String s) { name = s; }
}
static class UserWithdrawls {
    final User user;
    final double[] withdrawals;
    final ValueSummary summary;
    UserWithdrawls(User user, double[] withdrawals) {
        this.user = user;
        this.withdrawals = withdrawals;
        this.summary = ValueSummary.createFor(withdrawals);
    }
}
public static void main(String[] args) {
    UserWithdrawls[] userWithdrawls = {
            new UserWithdrawls(new User("John"), new double[] { 1, 2, 3}),
            new UserWithdrawls(new User("Doe"), new double[] { 10, 22, 30})
    };
    for (UserWithdrawls uw : userWithdrawls) {
        System.out.println("User: " + uw.user.name);
        System.out.println(uw.summary);
    }
}

Additional notes: If you are studying Computer Science, you'll learn in the future that the loop to calculate max, min, avg has a complexity of O(n). If the values array is fully loaded in memory, doing the max/min/avg in three different functions (thus reading the array 3 times) is still an algorithm of O(n) order with a bigger constant. With the power of today's computers the constant is so small, that most of the time you'll not get any gain from calculating min/max/avg in the same loop. In contrast you can gain code readability, for example in Groovy the minMaxAvg code could be written like this:

附加说明:如果您正在学习计算机科学,您将在未来学习计算max,min,avg的循环具有O(n)的复杂度。如果值数组在内存中完全加载,则在三个不同的函数中执行max / min / avg(因此读取数组3次)仍然是具有更大常量的O(n)阶的算法。凭借当今计算机的强大功能,常数非常小,大多数情况下,在同一循环中计算最小值/最大值/平均值时,您无法获得任何收益。相比之下,您可以获得代码可读性,例如在Groovy中,minMaxAvg代码可以像这样编写:

 def values = [2,3,4,5,6,7];
 println values.min()
 println values.max()
 println values.sum() / values.size()

#2


0  

Quick n Dirty: Use a second for loop for the second array, but do not reinitialize the min, max etc again.

Quick n Dirty:对第二个数组使用第二个for循环,但不要再次重新初始化min,max等。

Cleaner would be to make a class to hold the min, max etc, and a method that is passed this result object and an array. The method then scans the array and updates the result objects min, max etc. Call the method for each array.

Cleaner将创建一个类来保存min,max等,以及一个传递此结果对象和数组的方法。然后该方法扫描数组并更新结果对象min,max等。为每个数组调用方法。

#3


0  

Why don't you try to look at the code of Descriptive Statistics in the Commons Math library? Or better, use it instead of reinvent the wheel?

你为什么不试着在Commons Math库中查看描述性统计的代码?或者更好,使用它而不是重新发明*?

DescriptiveStatistics de = new DescriptiveStatistics();

de.addValue(..) // Your values
// Add more values

Double max = de.getMax();
Double min = de.getMin();
Double avg = de.getSum() / de.getN(); // or de.getMean();

And use an instance of DescriptiveStatistics for every array.

并为每个数组使用DescriptiveStatistics实例。

#4


0  

I think it would be better if you stored the details for each user in a seperate data structure like the following class named UserWithdrawals.

我认为如果将每个用户的详细信息存储在一个单独的数据结构中,如下面的名为UserWithdrawals的类,那会更好。

public class Program1{
    public static class UserWithdrawals{
        private LinkedList<Double> withdrawals=new LinkedList<>();

        public void add(Double amt){
            this.withdrawals.add(amt);
        }

        public Double getMinimum(){
            Double min=this.withdrawals.get(0);
            for(Double amt:this.withdrawals)
                if(amt.compareTo(min)<0) min=amt;
            return min;
        }

        public Double getMaximum(){
            Double max=this.withdrawals.get(0);
            for(Double amt:this.withdrawals)
                if(amt.compareTo(max)>0) max=amt;
            return max;
        }


        public Double getAverage(){
            Double sum=new Double(0);
            for(Double amt:this.withdrawals)
                sum+=amt;
            return sum/this.withdrawals.size();
            //this method will fail if the withdrawals list is updated during the iteration
        }

        /*You can also combine the three into a single method and return an array of Double object coz the iteration is same.*/

    }

    /*now you iterate over your two array lists (This wont work if the two array lists - 'Users' and 'Withdrawals' are of different size) and store the withdrawal data associated with a user in the corresponding map value - Maps or Associative arrays are a very basic data structure so your professor should not have any problems with this*/

    private HashMap<Integer,UserWithdrawals> withdrawals_map=new HashMap<>();

    public Program1(ArrayList<Integer> Users, ArrayList<Double> Withdrawals){
        for(int i=0;i<Users.size();i++){
            Integer user_no=Users.get(i);
            Double withdrawal_amt=Withdrawals.get(i);
            if(this.withdrawals_map.get(user_no)==null){
                this.withdrawals_map.put(user_no,new UserWithdrawals());
            }
            this.withdrawals_map.get(user_no).add(withdrawal_amt);
        }
    }

    public UserWithdrawals getUserWithdrawalsData(Integer user_no){
        return this.withdrawals_map.get(user_no);
    }
}