• 締切済み

インデックスソート

Javaに、インデックスソートを実行するライブラリーはありますか? 例えば、  {24,16,12,11,18,16} の入力に対して、昇順ソートしたときのインデックス位置  {3,2,1,5,4,0} を出力してくれるようなライブラリを探しています。 どなたか、ご存じないでしょうか? 以上、よろしくお願いいたします。

みんなの回答

  • 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 }

全文を見る
すると、全ての回答が全文表示されます。
  • setter1
  • ベストアンサー率0% (0/0)
回答No.8

私も今まで知らなかった口ですが、インデックスソートとは、実体は動かさずインデックスだけをソートするもの、だそうなので、素直にこういったコードではどうでしょう。 final int[] a = { 24, 16, 12, 11, 18, 16 }; Integer[] b = new Integer[a.length]; for (int i = 0 ; i < a.length ; i++) { b[i] = i; } Arrays.sort(b, new Comparator<Integer>() {  public int compare(Integer o1, Integer o2) {   return Integer.valueOf(a[o1]).compareTo(Integer.valueOf(a[o2]));  } }); System.out.println(Arrays.toString(b)); 実行すると [3, 2, 1, 5, 4, 0] です。 sortメソッドでComparatorを使えるのがオブジェクト配列だけなので、bはintではなくInteger配列にせざるを得なくなりますし、単なる連番の配列を作るだけにforループを使わなければならないのも格好悪いですが… commons-langを使えば一応、 Integer[] b = ArrayUtils.toObject(new IntRange(0,a.length).toArray()); と、bの作成は一行で書けます。このためだけにcommons-langを追加するのは本末転倒なので、他にも使うときだけに限るでしょうけど。

ggable
質問者

お礼

>プリミティブ配列をオブジェクト配列に変換しないでスマートに書けますか? 自己レスです。 すみません。意味不明なことを書いてしまいました。 上記の内容は、無視してください。 何を思ったかといえば、この方法と私の書いた方法とでは、  コンパレータの実装を無名クラスで書いたか有名クラスで  実装したかの違いしかないのでは? と、思った次第です。

ggable
質問者

補足

なるほど、これは素直な感じです。 ところで、この方法でArrays.sort(*)に倣って  sortIndex(byte[] a)  sortIndex(char[] a)    ~  sortIndex(double[] a)  sortIndex(Objct[] a) まで、全てのプリミティブ配列とオブジェクト配列までを 対象としたインデックスソートメソッドを実装するとなると、 どのようになるのでしょう。 プリミティブ配列をオブジェクト配列に変換しないでスマートに書けますか?

全文を見る
すると、全ての回答が全文表示されます。
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.7

確かに重複を見落としてました。そういう場合は下記で如何でしょう。 //サンプル配列 int[] a = {24,16,12,11,18,16}; //---- ここから本体 ---- TreeMap<Integer, List<Integer>> t = new TreeMap<Integer, List<Integer>>(); for ( int i = 0 ; i < a.length ; i++ ) {   List<Integer> v = t.get(a[i]);   if ( v == null ) v = new ArrayList<Integer>();   v.add(i);   t.put(a[i],v); } //結果の配列 int[] r = new int[a.length]; int i = 0; for ( Integer x : t.keySet() ) {   for ( Integer y : t.get(x) ) r[i++] = y; } //---- ここまで本体 ----

ggable
質問者

補足

これは、あまりにも。 言いにくいのですが、技巧的な上に実行効率もよくありません。 私が、N0.1の回答のところに書いたプログラムよりも、 何が優れていると思われているのでしょうか?

全文を見る
すると、全ての回答が全文表示されます。
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.6

//サンプルデータ int[] a = {24,16,12,11,18,16}; //----- ここから本体 ----- //並べ替え用TreeMap TreeMap<Integer, Integer> t = new TreeMap<Integer, Integer>(); //値と位置(インデックス)を仕込む for ( int i = 0 ; i < a.length ; i++ ) t.put(a[i],i); //インデックス用の配列(★結果の配列) int[] r = new int[a.length]; int i = 0; //TreeMapから値順に位置(インデックス)を受け取る for ( Integer x : t.keySet() ) r[i++] = t.get(x); //----- ここまで本体 ----- 独自にクラスを作るまでの必要は無いと思うんですけどね。

ggable
質問者

補足

インデックスソート対象の配列がユニークで無い場合、 Mapを使うと所望の結果は得られないでしょう。 そういう意味で、当初例示した配列の中に 16 を2つ入れているんですが... 実行して見られましたか?

全文を見る
すると、全ての回答が全文表示されます。
  • ninoue
  • ベストアンサー率52% (1288/2437)
回答No.5

サンプルプログラムを作成しましたのでコンパイル実行してみてください。 record no付き、int, float, string type data sort を行っています。  /* index sort program using java.util.Arrays.sort() routine */ import java.lang.reflect.Method; import java.lang.System; import java.util.Arrays; import java.util.Comparator; class MyObj implements Comparator { int idx; int age; float height; String name; public MyObj(int idx, int age, float height, String name) { this.idx=idx; this.age=age; this.height=height; this.name=name; return; } static void printheader() { System.out.println(" no idx age height name"); } static void printTitle(String titlestr) { System.out.println(titlestr); } static void printmyarray(MyObj[] myarray) { int len = myarray.length; int i; MyObj obj; for (i=0; i<myarray.length; i++) { obj = myarray[i]; if (obj != null) obj.printmyobj(i); } } void printmyobj(int no) { System.out.printf("%5d%5d%5d%7.1f %s\n",no,idx,age,height,name); } // dummy routine to suppress not overrided compare(Object,Object) public int compare(Object myobj, Object tgtobj) { return 0; } // compare age static Comparator ageOrder = new Comparator() { public int compare(Object myobj, Object tgtobj) { if (myobj==null||tgtobj==null) return 0; MyObj mobj = (MyObj)myobj; MyObj tobj = (MyObj)tgtobj; if (mobj.age < tobj.age) return -1; else if (mobj.age > tobj.age) return 1; else return 0; }}; // compare height static Comparator heightOrder = new Comparator() { public int compare(Object myobj, Object tgtobj) { if (myobj==null||tgtobj==null) return 0; MyObj mobj = (MyObj)myobj; MyObj tobj = (MyObj)tgtobj; if (mobj.height < tobj.height) return -1; else if (mobj.height > tobj.height) return 1; else return 0; }}; // compare name static Comparator nameOrder = new Comparator() { public int compare(Object myobj, Object tgtobj) { if (myobj==null||tgtobj==null) return 0; MyObj mobj = (MyObj)myobj; MyObj tobj = (MyObj)tgtobj; return mobj.name.compareTo(tobj.name); }}; } public class MySort { static Class myclass = MyObj.class; static Method cAge; static Method cHeight; static Method cName; static Object[] arglst = {Object.class, Object.class}; public static void main(String args[]) { int nentry = 8; MyObj[] myarray = new MyObj[nentry]; MyObj[] agearray, heightarray, namearray; myarray[0] = new MyObj(0, 20, 169.0f, "myself"); myarray[1] = new MyObj(1, 11, 167.1f, "brother"); myarray[2] = new MyObj(2, 32, 165.2f, "sister"); myarray[3] = new MyObj(3, 64, 171.4f, "father"); myarray[4] = new MyObj(4, 63, 164.3f, "mother"); agearray = new MyObj[nentry]; heightarray = new MyObj[nentry]; namearray = new MyObj[nentry]; System.arraycopy(myarray,0,agearray,0,nentry); System.arraycopy(myarray,0,heightarray,0,nentry); System.arraycopy(myarray,0,namearray,0,nentry); Arrays.sort(agearray, MyObj.ageOrder); Arrays.sort(heightarray, MyObj.heightOrder); Arrays.sort(namearray, MyObj.nameOrder); MyObj.printheader(); MyObj.printTitle("original array"); MyObj.printmyarray(myarray); MyObj.printTitle("age array"); MyObj.printmyarray(agearray); MyObj.printTitle("height array"); MyObj.printmyarray(heightarray); MyObj.printTitle("name array"); MyObj.printmyarray(namearray); return; } }

全文を見る
すると、全ての回答が全文表示されます。
  • ninoue
  • ベストアンサー率52% (1288/2437)
回答No.4

すみません。 sourceは src.lzh でなく src.zip として JDKに含まれています。  

全文を見る
すると、全ての回答が全文表示されます。
  • ninoue
  • ベストアンサー率52% (1288/2437)
回答No.3

sunの java standard libraryの中にsort routineが含まれています。 sample program, tutorialは 次の通り参照できます。 簡単にそのままコンパイル、コマンドラインからテストデータ入力実行が出来ます。 http://java.sun.com/javase/ja/6/docs/ja/api/ Arrays.binarySearch Arrays.sort http://java.sun.com/docs/books/tutorial/collections/algorithms/index.html Algorithms: Sorting 標準library sourceは、次のJDKをdownload,installすれば install directoryにsrc.lzh として含まれていますので、展開して参照することが出来ます。 http://java.sun.com/javase/downloads/index.jsp Java SE Development Kit(JDK) JDK 6 Update 16 Docs tutorial, docs, sourceは全てdownloadすることが出来ます。 sort routine以外についても色々と役に立ちますので参照してください。

全文を見る
すると、全ての回答が全文表示されます。
  • komi1341
  • ベストアンサー率65% (25/38)
回答No.2

質問への直接の回答ではなく、むしろ議論の範疇になりそうなので、役に立たないと思ったら無視してください。 私はインデックスソートなる機能を持つネイティブクラスがあるかどうか知りません。ただ、 > こういう基本的なアルゴリズムに関するようなクラスを > 自力で実装する必要があるというのも気色悪いですよね... この考え方に興味を持ちました。私は学生時代も含めると10年以上、プログラミングを扱う世界にいますが、インデックスソート、というものを扱ったことも、それが必要とされる場面も知らないのです。もちろんいろいろな業界・分野がありますし、私の知識や経験が万全だとはまったく思っていないので、ご質問に対して否定的な考えは持っていません。ただ、お考えになっている機能について、必要な人がいるかもしれないなとは思うものの、基本的な機能だから標準として実装されるべきだ、とまでは思えないのです。 試しに「インデックスソート」という単語でgoogleで検索をかけてみましたが、この質問も含め600件弱しか引っかからず、有効でない結果を差し引いたらその半分もなさそうです。それらを読む限りでは主にデータベース操作に関連して使われるアルゴリズムのようですが、それより検索結果の量が気になります。この「インデックスソート」という呼び名自体は「基本的」と呼べるくらいメジャーなものなのでしょうか? もし別の呼び名があるなら、それとjavaという検索ワードで探してみてはいかがでしょうか。 以上、少しでも参考になればと思います。

ggable
質問者

補足

>インデックスソート、というものを扱ったことも、 >それが必要とされる場面も知らないのです。 例えば、   MATLAB Function Reference   sort   http://www.mathworks.com/access/helpdesk_archive_ja_JP/r13/help/toolbox/matlab/ref/index.html?/access/helpdesk_archive_ja_JP/r13/help/toolbox/matlab/ref/sort.html&http://www.google.co.jp/search?q=matlab+sort+%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9&lr=lang_ja&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja:official&client=firefox-a      [B,INDEX] = sort(A) こんな感じです。 戻り値が複数ある時点で、多くの人はMATLABの関数に違和感を 感じるかもしれませんが、構造体(Javaのクラス)を定義して そのポインタ(オブジェクト)を1つ返すのと全く同等なことです。 MATLABには、実用的なライブラリが沢山存在するので、独自に クラスを設計する場合にも、非常に有益だと思われます。 具体的な使用例としては、  競馬のあるレースの3番人気の馬の馬体重は  何キログラムですか? という解を求めるプログラミングを書くとしましょう。 こんな場合に、  オッズ配列だけをインデックスソートして、  3番人気の馬を特定して、その馬体重を取り出す。 といった使い方をするということです。 それならば、馬構造体(オブジェクト)を馬体重をキーにして ソートすれば良いのではと思われるかもしれませんが、 馬構造体のサイズが非常に大きいときに、最終的に必要とされない データを含めてソートすることはヒープの無駄といえます。 また、この競馬の例では、馬番(馬名)というユニークなキーがあるので わざわざ新たにインデックスを生成してソートすることに 無駄があるのではと思われるかもしれませんが、この方法の利点は ユニークなキーを持っていないデータ構造でも、その中身を 一切気にせずに一意な方法でソート出来るということです。 ここまでの話では、いかにもオブジェクト指向的でないと 思われるかもしれませんが、その観点から言えば、  オブジェクト自体を並べ替えないで、ある項目でソートした  任意番目のオブジェクトを取り出したい という場合にインデックスソートが威力を発揮します。 日常的に、こういう要求もあるのではないでしょうか? >この「インデックスソート」という呼び名自体は「基本的」と >呼べるくらいメジャーなものなのでしょうか? 日常的な用語の名詞結合なので、なかなか目的の内容が 探しにくくなっています。 タグソートとも言いますが、こちらもGUIのタグばかりが ヒットして大変です。 mooter検索が登場したときには検索エンジンの世界も 様変わりするかと思われましたが、全く羊頭狗肉で 使い物にならないし。

全文を見る
すると、全ての回答が全文表示されます。
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1
ggable
質問者

お礼

NumberインターフェースがComparableインターフェースを extendsしてなかったので、補足のようにIndexedNumberクラスを 書く必要があるかと思いましたが、Numberの具象クラスで Comparableはimplementsされてました。 この不自然な仕様はなぜでしょう? というわけで、ある程度簡略化はされましたが、自力で こんなことを書く必要があるかどうかは、未だに疑問です。 import java.util.Arrays; public class ArrayIndexSorter { public static Integer[] toObject(int[] a) { Integer[] v = new Integer[a.length]; for (int i=0, n=a.length; i<n; i++) { v[i] = a[i]; } return v; } public static Double[] toObject(double[] a) { Double[] v = new Double[a.length]; for (int i=0, n=a.length; i<n; i++) { v[i] = a[i]; } return v; } /** * int値の配列を数値の昇順でインデックスソート */ public static int[] sortIndex(int[] a) { return sortIndex( toObject(a) ); } /** * double値の配列を数値の昇順でインデックスソート */ public static int[] sortIndex(double[] a) { return sortIndex( toObject(a) ); } /** * 要素の自然順序付けに従って、指定されたオブジェクトの配列を昇順でインデックスソート */ public static int[] sortIndex(Object[] a) { IndexedObject[] indexedObjects = new IndexedObject[a.length]; for (int i=0, n=a.length; i<n; i++) { indexedObjects[i] = new IndexedObject(i, a[i]); } Arrays.sort(indexedObjects); int[] b = new int[indexedObjects.length]; for (int i=0, n=b.length; i<n; i++) { b[i] = indexedObjects[i].getIndex(); } return b; } private static class IndexedObject implements Comparable<IndexedObject> { private int index; private Object object; public IndexedObject(int index, Object object) { this.index = index; this.object = object; } public int getIndex() { return index; } @SuppressWarnings("unchecked") public int compareTo(IndexedObject o) { return ((Comparable<Object>)object).compareTo(o.object); } } }

ggable
質問者

補足

とりあえず、ネイティブなライブラリが見つからなかったので、 自分で書いてみましたが、本当に無いのでしょうか? こういう基本的なアルゴリズムに関するようなクラスを 自力で実装する必要があるというのも気色悪いですよね... ネイティブなライブラリの存在をご存知の方がおられましたら ご教授ください。 import java.util.Arrays; /** * 配列をインデックスソートするためのクラスです。 */ public 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]); } 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 ); } /** * 要素の自然順序付けに従って、指定されたオブジェクトの配列を昇順でインデックスソートします。 */ public static int[] sortIndex(Object[] a) { IndexedObject[] indexedObjects = new IndexedObject[a.length]; for (int i=0, n=a.length; i<n; i++) { indexedObjects[i] = new IndexedObject(i, a[i]); } return toSortedIndex( indexedObjects ); } private static int[] toSortedIndex(Indexed[] 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 extends Indexed implements Comparable<IndexedNumber> { private Number value; public IndexedNumber(int index, Number value) { this.index = index; this.value = value;; } @Override public String toString() { return super.toString() + " [" + index + "," + value + "]"; } public int compareTo(IndexedNumber o) { if (o.value instanceof Long) { return value.longValue() - o.value.longValue() > 0 ? +1 : -1; } return value.doubleValue() - o.value.doubleValue() > 0 ? +1 : -1; } } /** インデックス付のオブジェクトを管理するクラスです。 */ private static class IndexedObject extends Indexed implements Comparable<IndexedObject> { private Object object; public IndexedObject(int index, Object object) { this.index = index; this.object = object; } @SuppressWarnings("unchecked") public int compareTo(IndexedObject o) { return ((Comparable<Object>)object).compareTo(o.object); } } /** インデックス付オブジェクトのインデックスを管理するクラスです。 */ private static class Indexed { protected int index; public int getIndex() { return index; } } }

全文を見る
すると、全ての回答が全文表示されます。

関連する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列として、それぞれ昇順でソートします。 範囲はその都度手動で複数行を全列選択します。 つまり、適宜、複数行を選択してからこのマクロを実行すれば常に先の形式でソートできるようにしたいです。  わかりにくい記述で恐縮ですがよろしくお願いします。

このQ&Aのポイント
  • 富士通FMVで高温の警告が頻繁に表示される問題が発生しています。掃除しても解消されない場合、小さなファンを設置することで問題が解消することがあります。
  • 富士通FMVの高温警告は、掃除をしてもなかなか解消されないことがあります。この場合、うしろに小さなファンを設置することで問題が解消されることもあります。
  • 富士通FMVで高温の警告が表示される場合、掃除をするだけでは解消されないことがあります。そのような場合は、うしろに小さなファンを置いて冷却することが有効です。
回答を見る