2012-08-11 129 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