2012-08-11 125 views
0

如何创建一个循环来生成2个数组列表的最小值,最大值,平均值,目前为止我只为单个数组列表生成了最小值,最大值和平均值。Java 2 array min max avg?

这些都是2个阵列用户[] &取款[]:

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 

这是我曾经尝试过,因为我不知道约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; 
} 

怎么办我从每个用户的提款数中打印最小,最大,平均值? :S

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

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

回答

0

分而治之:) 是的,我知道这是一种用于算法技术的术语,在这种情况下,我的意思是......小部分工作。

首先具有一个简单的数组的最小值,最大值,平均值:

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); 

注:既然你不能使用你的任务Java库,是很容易做你自己最小的版本/ MAX功能(读Math JavaDoc

现在你可以封装在一个函数的代码,你可以通过返回另一个数组开始:

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]); 
} 

使用数组有点难看,所以如果您创建一个类来保存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); 
} 

你不要在你的问题中指定,但我认为你必须为每个用户(也许每个取款是另一个数组)的数组。 现在您已经有底部零件了,我们可以切换到top-down thinking

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

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

好,但是这仅仅是想法,你仍然有其提款涉及aUser问题。您有几种选择在这里:

  1. 做一个“表”用户 - >提款,那是你试图用两个数组做。数组中的User索引就像一个“用户ID”。当您了解Map时,您会看到您可以使用更好的索引表示法。
  2. 有一个地图或阵列仅仅是一个优化,关系用户 - > Withdrawls的,但可以表示与对象(即UserWithdrawls)

选项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])); 
    } 
} 

选项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); 
    } 
} 

个其他注意事项:如果你正在学习计算机科学,您将了解,在未来的循环来计算最大值,最小值,平均值度为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() 
+0

我只能说,谢谢你嘘很多时间和精力用于解释这一点,它帮助我了解一切,并希望帮助别人.. 。,圣地亚哥! :) – Hotmama 2012-08-12 05:10:35

0

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

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

+0

是啊,我想用2种方法MINVALUE和MAXVALUE,然后调用它,但我应该创建这些最小值最大值avg func from“scratch”,这甚至意味着什么,因为我正在学习alice,而这是java 1或更高版本?笑O.o – Hotmama 2012-08-11 14:52:18

+0

Java有内置的数学函数 - 我觉得老师可能只是意味着你必须写自己的,而不是使用现有的方法。 – jeff 2012-08-11 14:57:25

+0

这是他所说的,所以我可以使用数学? “记住,学生都应该使用Java,可用库功能尽可能的代码,而不是一切从头开始。” – Hotmama 2012-08-11 15:06:50

0

为什么不尝试在Commons Math库中查看Descriptive Statistics的代码?或者更好地使用它,而不是重新发明轮子?

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(); 

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

+0

,因为这可以用for循环完成,我想知道如何...:S 除此之外,必须适用于任何具有x大小的数组文本文件... – Hotmama 2012-08-11 16:06:02

+0

LoL。这听起来更像是ACM的考试。是吗? – ElderMael 2012-08-11 16:13:05

0

我认为如果您将每个用户的详细信息存储在一个单独的数据结构(如以下类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); 
    } 
} 
+0

也有许多不同的方式来完成相同的,取决于所需的优化 – 2012-08-11 18:22:09