0

2 つの配列リストの最小値、最大値、平均値を生成するループを作成するにはどうすればよいですか。これまで、単一の配列リストの最小値、最大値、平均値を合計で生成しただけです。

これらは User[] と Withdrawals[] の 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 の利用可能なライブラリ機能を使用する代わりに、すべてをゼロから作成することです。

4

5 に答える 5

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);
    }
}
于 2012-08-11T18:19:57.577 に答える
0

Quick n Dirty: 2 番目の配列に 2 番目の for ループを使用しますが、min、max などを再度初期化しないでください。

よりクリーンなのは、最小値、最大値などを保持するクラスと、この結果オブジェクトと配列を渡すメソッドを作成することです。次に、メソッドは配列をスキャンし、結果オブジェクトの最小値、最大値などを更新します。配列ごとにメソッドを呼び出します。

于 2012-08-11T14:46:55.613 に答える
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 ライブラリを使用できないため、最小/最大関数の独自のバージョンを簡単に実行できます ( 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]);
}

配列の使用は読みにくいので、最小値、最大値、平均値を保持するクラスを作成することをお勧めします。コードを少しリファクタリングしましょう。

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

質問では指定していませんが、ユーザーごとに配列があると思います(おそらく、各引き出しは別の配列です)。下の部分ができたので、トップダウンの考え方に切り替えることができます。

したがって、コードは次のようになります。

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

わかりましたが、これは単なるアイデアです。aUser とその引き出しを関連付けるにはまだ問題があります。ここにはいくつかのオプションがあります。

  1. 「テーブル」ユーザー - >引き出しを作成します。これが、2つの配列でやろうとしていることです。配列内のユーザー インデックスは、「ユーザー ID」のように機能します。Map について学習すると、インデックスのより良い表現を使用できることがわかります。
  2. Map または配列を持つことは、関係 User->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) の複雑さを持っていることを将来学習します。値配列がメモリに完全にロードされている場合、3 つの異なる関数で最大/最小/平均を実行する (つまり、配列を 3 回読み取る) ことは、より大きな定数を使用した O(n) オーダーのアルゴリズムです。今日のコンピューターの能力では、定数は非常に小さいため、ほとんどの場合、同じループで最小/最大/平均を計算しても何の利益も得られません。対照的に、コードを読みやすくすることができます。たとえば、Groovy では、minMaxAvg コードは次のように記述できます。

 def values = [2,3,4,5,6,7];
 println values.min()
 println values.max()
 println values.sum() / values.size()
于 2012-08-11T18:32:51.717 に答える
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 のインスタンスを使用します。

于 2012-08-11T15:46:40.517 に答える
0
  1. C++ STL Sort 関数を使用して、1 列目に基づいて O(log(n)) の 2D 配列を並べ替えます。
  2. O(n) をトラバースして平均を計算し、MaxAverage を更新します。

    // Driver function to sort the 2D vector
    // on basis of a particular column
    
    bool sortcol( const vector<int>& v1, const vector<int>& v2 ) {
        return v1[0] < v2[0];
    }
    
    void sortMatrix()
    {
    // Initializing 2D vector "vect" with
    // values S_ID,MARKS
    vector< vector<int> > vect{{1,85}, {2,90}, {1,87}, {1,99}, {3,70}};
    
    // Number of rows
    int m = vect.size();
    
    // Number of columns
    int n = vect[0].size();
    
    // Use of "sort()" for sorting on basis
    // of 1st column
    sort(vect.begin(), vect.end(),sortcol);
    
    float maxAverage=-1;
    int id=1; // assuming it starts from 1.
    float sum=0;
    int s=0; // size of marks per student to calculate average
    for( int i=0; i<m; i++ )
    {
        sum+=vect[i][1];
        s=s+1;
        if( i+1!= m && vect[i+1][0] != vect[i][0] ){// gotten all the marks of this student
            maxAverage = maxAverage>sum/s? maxAverage:sum/s;
            id = vect[i][0];
            s=0;
            sum=0;
        }
    }
    cout<<"ID: "<<id<<"\tValue: "<<maxAverage<<endl;
    }
    

出力:

ID: 2   Value: 90.3333
于 2019-09-21T09:23:54.950 に答える