5

double 値を含む 2 次元の ArrayList があります。

ArrayList<ArrayList<Double>> data = new ArrayList<ArrayList<Double>>(); 

従来の配列と同様に、このマトリックスの「列」を並べ替えたいと思います。サブ ArrayLists で同じインデックスを持つアイテムを取得して並べ替えたいと思います。すべての列に対して Collections.sort() を呼び出すように...行とは、外側のレベルと内側のレベルが列であることを意味します。

これを行う適切な方法は何ですか?マトリックスを反復処理して反転し、各行を Collections.sort() でソートすることを考えましたか? しかし、マトリックスは約 400*7000 であるため、最適なソリューションではない可能性があります。

行列のサイズが不明なため、従来の配列は使用できません。

手伝ってくれてありがとう。

4

7 に答える 7

3

したがって、これは反転のアイデアに似たオプションですが、一度に1つの列を作成し、並べ替えて破棄することで、全体を反転するのではありません。

ArrayList<ArrayList<Double>> data = new ArrayList<ArrayList<Double>>(); 

for(int c=0; c<data.get(0).size(); c++) {
    List<Double> col = new ArrayList<Double>();
    for( int r=0; r<data.size(); r++ )
        col.add( data.get(r).get(c) );

    Collections.sort(col);

    for( int r=0; r<col.size(); r++ )
        data.get(r).set( c, col.get(r) );
}

テーブルの列のビューをリストとして提供する独自のクラスを作成するオプション以外に、より効率的なものを取得できるとは思えません。

于 2012-04-05T21:11:29.620 に答える
3

このようなことをします:

    final int COLUMN = 5;
    Comparator<ArrayList<Double>> myComparator = new Comparator<ArrayList<Double>>() {
        @Override
        public int compare(ArrayList<Double> o1, ArrayList<Double> o2) {
            return o1.get(COLUMN).compareTo(o2.get(COLUMN));
        }
    };
    Collections.sort(list, myComparator);

COLUMNを、並べ替える列に設定します。

アップデート:

はい、これはまったく機能しません。

私は、元のリストをラップする独自のリストを作成するというahaninの2番目の提案が好きです。get()によって返されたオブジェクトもラップして、変数wrappedListに列の値が含まれ、wrappedList.get(0)も値の列を返すようにする必要があります。その後、並べ替えが機能します。あなたがあなたのリストで働くためにCollections.sort()のためにあなたが実行しなければならない最小のメソッドは何であるかと思います。

他の誰かのクイックソートを取得して、リストで機能させるのがおそらく最も簡単でしょう。

これが1つの実装です:http ://www.vogella.de/articles/JavaAlgorithmsQuicksort/article.html

于 2012-04-05T20:43:34.257 に答える
2

逆行列構造を認識する独自の並べ替えアルゴリズムを実装するか、構造をラップして列を表す Collection の実装を作成し、後で Collections の引数として使用できるようにするという 2 つのクレイジーなアイデアを思いつきました。選別()。ArrayList を使用すると、これはかなり高速になります。

于 2012-04-05T20:29:32.180 に答える
2

データをオブジェクト配列に変換するこの状況へのアプローチを次に示します。列を好きなように変更します。

final int column = 3;
ArrayList<ArrayList<Double>> data = new ArrayList<ArrayList<Double>>(); 

// Convert data into an object array
Object [] temp = data.toArray();

Arrays.sort(temp, new Comparator<Object>() {
    @Override
    public int compare(Object o1, Object o2) {
        // Get inner arrays to be compared by type-casting
        ArrayList<Double> temp1 = (ArrayList<Double>) o1;
        ArrayList<Double> temp2 = (ArrayList<Double>) o2;

        // Then compare those inner arrays' indexes
        return temp1.get(column).compareTo(temp2.get(column));
    }
});

// Clear the old one and add the ordered list into
data.clear();

for(Object o: temp)
{
    data.add((ArrayList<Double>) o);
}
于 2012-10-12T17:33:25.360 に答える
0

ストレージに問題がなければ、ArrayListでSortedMapを使用できると思います。そうすれば、要素の並べ替えについて心配する必要はありません。

ArrayList<SortedMap<Double,byte>> data;
于 2012-04-05T20:42:10.653 に答える
0

あなたのQを正しく理解しているかどうかはわかりませんが、これはすべての「列」をソートします(外側のレベルが行で、内側のレベルが列であると仮定します):

    final ArrayList<ArrayList<Double>> data = new ArrayList<ArrayList<Double>>(); 
    //...

    final Integer[] rows = new Integer[data.size()];
    for(int i=0;i<rows.length;i++)
        rows[i]=i;

    int cols = data.get(0).size();
    for(int c=0;c<cols;c++)
    {
        final int colidx = c;
        Arrays.sort(rows,new Comparator<Integer>(){
            @Override
            public int compare(Integer arg0,
                    Integer arg1) {
                return data.get(arg0).get(colidx).compareTo(data.get(arg1).get(colidx));        
            }});    

        for(int i=0;i<rows.length;i++)
            data.get(i).add(colidx+1,data.get(rows[i]).get(colidx));
        for(int i=0;i<rows.length;i++)
            data.get(i).remove(colidx);
    }
于 2012-04-05T20:59:36.963 に答える
0

いずれにせよ、それらを並べ替えるには、すべての要素にアクセスする必要があります。だからあなたができることはこれです。

int temp[] = new temp[col.length];
int x = 0;
while(x < row.length)
{
    for(int i = 0; i<col.length; i++)
    {
        temp[i] = mat[x][i];
    }
    sort(temp);
    for(int i = 0; i<col.length; i++)
    {
        mat[x][i] = temp[i];
    }
x++;
}

ここでの実行時間は になりますO(n^2logn)が、400 個の double のみをソートしているので、それほど時間はかかりません。マトリックスの各要素に少なくとも 1 回アクセスする必要があるため、下に移動することはできません。O(n^2)

于 2012-04-05T21:45:38.493 に答える