• 締切済み

インデックスソート

hrm_mmmの回答

  • hrm_mmm
  • ベストアンサー率63% (292/459)
回答No.9

インデックスソートの意味がどうにも解りにくく様子をみてましたが回答8を読んで納得です。 人のアイデアで勝負みたいになりますが、回答8のルーチンを汎用化してみました、Comparableを実装したクラスの配列なら何でもokです。 しかし、primitive型は、、、ラッパー型に変換してからMySortUtil.sortIndex(final Comparable[] a)を呼ぶか、MySortUtil.sortIndexの方に、それぞれの型の引数を取るメソッドを作るか、、、さてどっちがいいだろう?ってユーザーにしてみれば、メソッドオーバーロードしてある方がいいに決まってますよね。 それから返り値型はint[] に変換した方がいいのだろうか??? 以下長文失礼します。 /* java 5 でcompile */ import java.util.Comparator; import java.util.Arrays; public class SortTest { public static void main(String[] args) { Integer[] b; Integer[] aa = { 24, 16, 12, 11, 18, 16 }; b = MySortUtil.sortIndex(aa); System.out.println("元" + Arrays.toString(aa)); System.out.println("index sorted"+Arrays.toString(b)); Character[] cc = {'b', 'k','a','z','b'}; b = MySortUtil.sortIndex(cc); System.out.println("元" + Arrays.toString(cc)); System.out.println("index sorted"+Arrays.toString(b)); byte[] bb = {'f', 'b','a','z','b'}; b = MySortUtil.sortIndex(bb); System.out.println("元" + Arrays.toString(bb)); System.out.println("index sorted"+Arrays.toString(b)); int[] bp; double[] dp = {1.0, 11.99, 98.098, 0.999, 6.09}; Double[] dw = new Double[dp.length] ; for(int i=0; i<dp.length; i++){dw[i]=Double.valueOf(dp[i]);} System.out.println("元" + Arrays.toString(dp)); b = MySortUtil.sortIndex(dw); /* double[] 用のメソッドをまだ書いてないのでDouble[]型の方のみ */ System.out.println("index sorted"+Arrays.toString(b)); bp = ArrayIndexSorter.sortIndex(dp); /* 書き換え版 ArrayIndexSorter */ System.out.println("index sorted2:"+Arrays.toString(bp)); bp = ArrayIndexSorter.sortIndex(dw); System.out.println("index sorted3:"+Arrays.toString(bp)); } } class MySortUtil{ public static Integer[] sortIndex(final Comparable[] a){ Integer[] b = new Integer[a.length]; for (int i = 0 ; i < a.length ; i++) { b[i] = i; } Arrays.sort(b, new Comparator<Integer>() { @SuppressWarnings("unchecked") // この行がないとwarningがでる public int compare(Integer o1, Integer o2) { return a[o1].compareTo( a[o2]); } }); return b; } /* byte[]引数のものだけ作ってみた、あとはコピー&ペーストして、引数のbyte[]と比較用Byteの型を各型に置き換えればできあがりではある。*/ public static Integer[] sortIndex(final byte[] a){ Integer[] b = new Integer[a.length]; for (int i = 0 ; i < a.length ; i++) { b[i] = i; } Arrays.sort(b, new Comparator<Integer>() { @SuppressWarnings("unchecked") public int compare(Integer o1, Integer o2) { return Byte.valueOf(a[o1]).compareTo( Byte.valueOf(a[o2]) ); /* 直接引き算して、とも思ったが範囲外エラーが出ては困るので、やはり、ラッパー型でcompareToを使うのがよいようです。*/ } }); return b; } } /* >コンパレータの実装を無名クラスで書いたか有名クラスで実装したかの違い これについては、インラインで書くことによって、メソッド内の変数を使って直接比較できる=新たなobject作成時間節約ということが利点。 逆にprimitive型毎に無名コンパレータがたくさんできてしまうということでもあるけど。 No1の補足に記述されたクラスですが、innerクラスを3つも作らなくてもいいのではって思ったのと、NumberじゃなくてComparable型でvalueを保持すればcompareToメソッドが使えるのと、自作のComparable実装クラスの配列でもこのソートが出来るようになるので、以下のようにしてみました。 */ /** * 配列をインデックスソートするためのクラスです。 * ※マークで変更部分を説明 */ class ArrayIndexSorter { /** * 指定された byte値の配列を数値の昇順でインデックスソートします。 */ public static int[] sortIndex(byte[] a) { IndexedNumber[] indexedNumbers = new IndexedNumber[a.length]; for (int i=0, n=a.length; i<n; i++) { indexedNumbers[i] = new IndexedNumber(i, a[i]); } return toSortedIndex( indexedNumbers ); } /** * 指定された int値の配列を数値の昇順でインデックスソートします。 */ public static int[] sortIndex(int[] a) { IndexedNumber[] indexedNumbers = new IndexedNumber[a.length]; for (int i=0, n=a.length; i<n; i++) { indexedNumbers[i] = new IndexedNumber(i, a[i]); /* ※配列全体でなければ、 Comparable value =1; も問題なく代入できる */ } return toSortedIndex( indexedNumbers ); } /** * 指定された long値の配列を数値の昇順でインデックスソートします。 */ public static int[] sortIndex(long[] a) { IndexedNumber[] indexedNumbers = new IndexedNumber[a.length]; for (int i=0, n=a.length; i<n; i++) { indexedNumbers[i] = new IndexedNumber(i, a[i]); } return toSortedIndex( indexedNumbers ); } /** * 指定された float値の配列を数値の昇順でインデックスソートします。 */ public static int[] sortIndex(float[] a) { IndexedNumber[] indexedNumbers = new IndexedNumber[a.length]; for (int i=0, n=a.length; i<n; i++) { indexedNumbers[i] = new IndexedNumber(i, a[i]); } return toSortedIndex( indexedNumbers ); } /** * 指定された double値の配列を数値の昇順でインデックスソートします。 */ public static int[] sortIndex(double[] a) { IndexedNumber[] indexedNumbers = new IndexedNumber[a.length]; for (int i=0, n=a.length; i<n; i++) { indexedNumbers[i] = new IndexedNumber(i, a[i]); } return toSortedIndex( indexedNumbers ); } /** * 要素の自然順序付けに従って、指定されたオブジェクトの配列を昇順でインデックスソートします。 * ※どのみちComparableを実装してないとソートできないのだから、Comparable[] 型で受け取りましょう */ public static int[] sortIndex(Comparable[] a) { IndexedNumber[] indexedObjects = new IndexedNumber[a.length]; for (int i=0, n=a.length; i<n; i++) { indexedObjects[i] = new IndexedNumber(i, a[i]); } return toSortedIndex( indexedObjects ); } private static int[] toSortedIndex(IndexedNumber[] indexed) { Arrays.sort(indexed); int[] b = new int[indexed.length]; for (int i=0, n=b.length; i<n; i++) { b[i] = indexed[i].getIndex(); } return b; } /** インデックス付の値を管理するクラスです。 */ private static class IndexedNumber implements Comparable<IndexedNumber> { private Comparable value; /* ※NumberがComparableではないので、Comparable型にする */ private int index; /* ※IndexedObject もIndexedNumberで共通処理できるようになるとIndexedクラスの必要性も無くなる */ int getIndex() { return index; } /* ※Comparable型にすれば、Object[] 用のクラスを別にする必要がない */ public IndexedNumber(int index, Comparable value) { this.index = index; this.value = value;; } @Override public String toString() { return super.toString() + " [" + index + "," + value + "]"; } public int compareTo(IndexedNumber o) { return value.compareTo( o.value) ; } } // inner class end }

関連するQ&A

  • アルファベットのソート

    Javaでクイックソートを使って、アルファベットを昇順に(スペースより小文字の方が大きい、小文字より大文字のほうが大きいものとする)並べ替えたいのですが、比較方法がよくわかりません。ご教授お願いいたします。 入力は、キーボードからの入力でchar型配列です。

    • ベストアンサー
    • Java
  • Pythonの2次元配列のソート

    Python3の2次元配列のソートについて教えて下さい [[1, 2], [1, 3], [2, 4]]のようなリストのソートで 昇順ソートでインデックス0が同じならインデックス1は降順でソートしたいと思ってます。 結果が以下のようになるようにしたいです 1 3 1 2 2 4 よろしくおねがいします。

  • ソートプログラムについて

    ソートプログラムとして以下のように作成しました。 int main( ) { int i, j, temp; int ten[10] = { 98,34,67,89,99,23,54,21,10,65 }; for (i=0; i< 9; i++) { for(j=i+1; j<10; j++) { if (ten[i] < ten[j]) { temp = ten[i]; ten[i] = ten[j]; ten[j] = temp; } } } for (i = 0; i < 10; i++) { printf("SORT[%d] = %d\n",i,ten[i]); } } このプログラムを昇順で同じ数字が入力された場合、出力表示として 例: SORT[1]=99 SORT[2]=98 SORT[2]=98 SORT[3]=89 SORT[4]=70 というようにしたいのですが、プログラムをどのように 書いていけば良いのかわかりません。 例のような出力にするにはどのようにすればいいのでしょうか 教えて下さい。

  • C#でバブルソート

    テキストボックスに任意の整数を複数個入力し、ボタンを押すことで入力した数字を別のテキストボックスに昇順・降順表示するプログラムを作りたいと思っています。 例えば 入力用テキストボックスに1、10、5をキーボードで入力 ↓ 作っておいた「昇順に並び替え」のボタンをクリック ↓ 出力用テキストボックスに1、5、10と表示される (「降順に並び替え」のボタンをクリックした場合は、10、5、1と表示) といった感じです。 バブルソートを使って作りたいのですが、超初心者のため、数字同士の比較?や、テキストボックスへの出力の仕方が全く分かりません。 分かりにくい文章のみの状況説明になってしまいましたが、ご指導よろしくお願いします。 マイクロソフトのビジュアルのC#プロジェクトです。

  • VBAでもsort

    今、FOM出版のVBAの実践編を勉強中です。宜しくお願いします。 その中の「sort」メソッドでどうしても納得できず、前に進めない事があります。 構文:rangeオブジェクト.sort(kye1,order1,key2,order2,key3,order3,header) これは理解できるし、どこも省略せずに記入すればその通りに動くのですが orderは省略でき、省略した場合は昇順に並べ替えられると本には載っているのですが 私の記述はうまくいきません。 なぜ、こうなるのか教えてください。 B3  C3   D3 No.  氏名  住所 という表があり、氏名を昇順に並べようとしています。 構文通りに Range("B3").Sort key1:=Range("C3"), order1:=xlAscending, header:=xlyes とすれば問題なく Range("B3").Sort key1:=Range("C3"), header:=xlyes と記述すると、最初はうまくいきますが もう一度試そうと氏名欄を降順に並べ替え、それから実行すると動きません。 また、No.欄を昇順に並べ替えて実行するとちゃんと動き No.を降順に並べ替えて、氏名欄を昇順で並べ替えを実行すると氏名欄も降順で 並べ替えられてしまいます。 なぜ、こんな安定しない動きをするのかがわかりません。 初歩的な質問で申し訳ないのですが、どうしても気になって先に進めないので どうぞ教えてください。 ちなみに、もう一度試そうとNo.欄を並べ替える時は、エクセルの昇順降順アイコンで 並べ替えています。これが問題なのでしょうか?

  • java ソート

    java ソート ソートプログラムを作ってみましょう ? double型の配列とメソッドを持つクラスを定義 ? コンストラクタで配列を初期化(0.0で初期化) ?配列を昇順,降順に並び替えるメソッドを持つこと ? 2種類のメソッドを持っても良い ? 引数の値で変えても良い ? ソート済み配列をチェックするメソッドを持つこと ? 1000000要素程度のソーティングで時間計測 課題です 全く手が出せず困ってます・・・。 ヒント、手順、解答 なんでも良いので、救いの手をお願いします!!

  • モジュール分割

    以下のようなJAVAプログラムを作成しなさい。 ただし単一のクラスのmainメソッドのみから構成されるプログラムにすること 1個以上の整数を入力して、それらの合計、平均、最大値、最小値を求めて出力する。 されに入力された整数を、入力された順序で表示する。入力された順序と逆に表示する。昇順にソートして表示する。降順にソートして表示する。これらの処理は、整数の入力後に、繰り返し入力できる。 動作例 入力する整数の個数(1個以上)を指定してください 4 整数を入力してください 1個目:3 2個目:6 3個目:2 4個目:7 処理を選択してください 1.合計 2.平均 3.最大 4.最小 5.順表示 6.逆順表示 7.昇順ソート 8.降順ソート 0.終了 2 <平均> 4.5 処理を選択してください 1.合計 2.平均 3.最大 4.最小 5.順表示 6.逆順表示 7.昇順ソート 8.降順ソート 0.終了 0 というものなのですが自分でやってみたところ一つ一つ動作することはできるのですが、 繰り返しの処理になると何故か終了が機能しなくて困っています。 もうあまり時間もなくて出来れば解答をお願いしたいのですけど、 どなたかわかる方がおりましたらお願いいたします。

  • ソート処理

    javaでソート処理を行いたいのですが、 ソート対象がカナ文字です・・・。 そこでまず技術的に可能であるか教えて下さい。 また、何か良い方法をご存知であれば教えて下さい。 宜しくお願いします。

    • ベストアンサー
    • Java
  • 挿入ソートとマージソート

    挿入ソートとマージソートの問題を解いているのですが、 途中で行き詰ってしまいました。 (問題文) サイズnの入力に対して、挿入ソートの実行には8n~2ステップかかり、 マージソートの実行には64nlnnステップかかる。 挿入ソートがマージソートに勝るnの値を求めよ。 補足:ln=eを底とするlog (挿入ソートがマージソートに勝る=挿入ソートがマージソートより実行時間が早い) 8n~2 <= 64nlnn 8lnn=n e~n=n~8 こういう感じで自分なりに考えてみたのですが、nの値をどのように出して良いのかわからず困っています。 どなたかご教授いただける方いましたらよろしくお願いします。

  • エクセルのソートのマクロ

    エクセルでのソートのマクロを教えてください。  範囲選択は手動でその都度変更します。優先列、昇順は変更ありません。 例えば、AからE列までデータがあり、第一優先列をD列、第二優先列をA列として、それぞれ昇順でソートします。 範囲はその都度手動で複数行を全列選択します。 つまり、適宜、複数行を選択してからこのマクロを実行すれば常に先の形式でソートできるようにしたいです。  わかりにくい記述で恐縮ですがよろしくお願いします。