Comparatorを使用したソートについて

このQ&Aのポイント
  • Javaのバージョン1.5を使用して、Comparatorを使ったソートを行っています。
  • ソートするキーのシフトJISコードを基準に昇順で並べ替えたいのですが、うまくいきません。
  • 特に2バイト文字のソート順について、どう処理すれば良いのかわかりません。
回答を見る
  • ベストアンサー

Comparatorを使用したソートについて

Javaのバージョンは1.5です。 Comparatorを使用してソートを行っています。 ソートをシフトJISコード順とするため 下記のようなクラス、メソッドを作成しています。 public class ExmComparator implements Comparator<Object> { public int compare(Object obj1, Object obj2) { byte[] b1 = obj1.toString().getBytes("SJIS"); byte[] b2 = obj2.toString().getBytes("SJIS"); int len; if (b1.length < b2.length) { len = b1.length; } else { len = b2.length; } int s1h, s2h; for (int i = 0; i < len; i++) { s1h = b1[i]; s2h = b2[i]; if (!(s1h == s2h)) { return s1h - s2h; } } return b1.length - b2.length; } } ソートするキー(名称+コード)が "-0001","テレビ0002","電話0003","PC0004"の場合はシフトJISコードの昇順に "-0001","PC0004","テレビ0002","電話0003"としたいのですが、 "テレビ0002","電話0003","-0001","PC0004"とソートされてしまいます。 半角ハイフンは名称がない場合の代替名称です。 シフトJISコードは - :0x002d P :0x0050 テ:0x30c6 電:0x9364 なのでこの通りにソートされるのではないかと思ったのですが、 2バイト文字はどうなんでしょうか…。

  • Java
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

とりあえず getBytes で得られたバイト列を調べて「期待通りのソート順になるようなもの」かどうかを確認してみてはどうでしょうか.

superss28
質問者

お礼

最初の段階で二バイト文字かどうかを判定して そこからソートを行うようにしたところうまくいきました。 ご回答ありがとうございました。

関連するQ&A

  • ソート Comparator

    Integer型の変数num(10,4,8,6,9,5)をそれぞれ含むオブジェクト配列aryがあり、それをソートするため Arrays.sort(arry,sortLogic); とした場合、 Comparatorインターフェースを実装したクラスsortLogic内のメソッドで public int compare(Object object1, Object object2) {   return ((ary)object1).compareTo(((ary)object2).num); } とすると、昇順にソート(修正ソートマージ)、また、 return ((ary)object1).compareTo(((ary)object2).num); とすると降順にソートされるみたいなのですが、どのような手順(アルゴリズム)でソートされるのでしょうか?

    • ベストアンサー
    • Java
  • 多次元配列のソートがうまくいかない

    多次元配列のソートがうまくいかない 質問失礼します. 以下のような,String型,int型,double型の混在した多次元配列([3][3]の配列)をソートするプログラムを作成しました. このプログラムでは3番目の項目でソートを行っています. 問題点なのですが, 3番目の項目がdouble型の一桁(例えばarray[1][2]が2.0)ならばうまくソートできるのですが, 一つを2桁(例えばarray[1][2]を10.0)にすると何故か先頭の数(10.0の場合1)を基準にソートされてしまっているようです・・・ 配列へのデータの入れ方が間違っているのでしょうか? 原因がはっきりわからず困っているのですが, わかる方いましたらよろしくお願いします. public class Sort_test { /** * @param args */ public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ String[][] array = new String[3][3]; array[ 0 ][ 0 ] = "A"; array[ 0 ][ 1 ] = 2001+""; array[ 0 ][ 2 ] = 9.0+""; array[ 1 ][ 0 ] = "B"; array[ 1 ][ 1 ] = 1001+""; array[ 1 ][ 2 ] = 2.0+""; array[ 2 ][ 0 ] = "C"; array[ 2 ][ 1 ] = 3001+""; array[ 2 ][ 2 ] = 6.0+""; TheComparator comparator = new TheComparator(); // 3番目の項目でソートするように設定 comparator.setIndex( 2 ); // ソート実施 Arrays.sort( array, comparator ); dump(array); } public static void dump( String[][] array ) { for ( int i = 0;i < array.length;i++ ) { for ( int j = 0; j < array[ i ].length;j++ ) { System.out.print( "\t" + array[ i ][ j ] ); } System.out.println(); } } } //多次元配列ソート用クラス class TheComparator implements Comparator { /** ソート対象のカラムの位置 */ private int index = 0; /** ソートするためのカラム位置をセット */ public void setIndex( int index ) { this.index = index; } public int compare( Object a, Object b ) { String[] strA = ( String[] ) a; String[] strB = ( String[] ) b; return ( strA[ index ].compareTo( strB[ index ] ) ); } }

    • ベストアンサー
    • Java
  • この警告はどうすれば?

    以下のメソッドを含むプログラムをEclipseで作成している際に次のような警告が発生しました。 型の安全性:型Comparator の式は、未検査の型変換を使用してComparator<? super T>に準拠するようにする必要があります。 型の安全性:型 Arrays の総称メソッド sort(T[], Comparator<? super T>)の未検査の呼び出し sort(Object[],Comparator)がありました。 コンパイルして実行する分には、なんら問題ないのですが、この警告の意味と解決策が分からないままにしておくのは気持ち悪いので、分かる方がいらしたら教えてください。 static void sortName(){  String array[] = new String[4];  array[0] = "abba";  array[1] = "abab";  array[2] = "aaaa";  array[3] = "aabb";  Comparator asc = new Comparator() {   public int compare(Object obj0, Object obj1) {    String nameKana0 = (String)obj0;    String nameKana1 = (String)obj1;    int ret = 0;    ret = nameKana0.compareTo(nameKana1);    return ret;  }  };  Comparator comparator = asc;  Arrays.sort(array, comparator); // 配列をソート  for (int i = 0; i < array.length; i++)   System.out.println(array[i]); }

    • ベストアンサー
    • Java
  • ComparableとComparatorの違いについてわからなくて困っています。

    ComparableとComparatorの違いについてわからなくて困っています。 以下のURLのサイトを記事を見ているのですが、 http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000179.html http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000180.html java.lang Comparableインタフェース メソッド public int compareTo(Object o) java.util Comparatorインタフェース メソッド public int compare(Object o1, Object o2) public boolean equals(Object obj) これらの違いについてなのですが、URLの記事では、 ・Comparableインターフェイスの実装クラスにしてcompareTo()メソッドを実装するのは、比較対象が明確であり、比較結果が一般的に分かりやすく容易に想像できる場合にのみとした方がよい ・Comparatorは任意の順番でソートしたい場合にも使用できる。例えば、昇順ではなく降順でソートしたい場合や、複数のデータを持つクラスについて細かく比較方法する場合 と記事にありますが、説明がうまく解釈できないです。 ・Comparableは主にラッパークラスやStringなどで使用するためのものなのでしょうか?(実装してるからそうだとは思いますが) 比較対照が明確なので compareToのreturn文で 除算するだけで可能? ・ComparatorはArraysやコレクション、自作クラス向けに任意の順番でソートするためのものなのですか? 自作クラスについてはComparableでもcompareTo()をオーバーライドすれば同じことが可能? 通常はComparator実装クラスのcompare()の中にreturn文でcompareTo()を使用しているような気もします。 この方法だとObject型で引数を渡して、int型に変換して比較になると思いますが、 StringだとComparableを実装してるから、戻り値でint型が返るのかな、 public int compare(String s1, String s2) { return s2.compareTo(s1) } つまり、自作クラスはインスタンスフィールドにある基本型やObject型(String, Integerなど)の値を使い、 基本型においては除算を使用し、オブジェクト(Comparableを実装しているもの)に対してはcompareTo()で比較するのでしょうか? (これで解決したような気もしますが) 質問がわかりずらくてすみません。何か解釈の間違いがあればご指摘お願いします。

  • 昇順ソート

    sort.txtから読み込んだ値を 昇順でソートして出力するにはどうしたらよいでしょうか? #include <stdio.h> #include <stdlib.h> #include <string.h> #include <search.h> /* 比較関数 */ int strcmp_asc(const void *, const void *); int main(void) { FILE *fin, *fout; int i; int length; char s[256], s2[256]; if( (fin=fopen("sort.txt","r"))==NULL) { printf("入力ファイルがオープンできません\n"); exit(EXIT_FAILURE); } if( (fout=fopen("file2.txt","w"))==NULL) { printf("出力ファイルがオープンできません\n"); exit(EXIT_FAILURE); } while(fgets(s, 256, fin) != NULL) { /* 要素数を求める */ length = sizeof(s) / 256; /* 昇順でソート */ qsort(s, length, 256, strcmp_asc); /* memset(s2, NULL, sizeof(s2)); for (i = 0; i < length; i++) { } */ fprintf(fout,"%s\n",s2); } fclose(fin); fclose(fout); return 0; } int strcmp_asc(const void *sa, const void *sb) { return strcmp((char *)sa, (char *)sb); } sort.txt 50 45 35 25 15 10 5 1 32 46 8 7 9 19 18 14 16 13 12 17 11 20 40 30 31 3 2 37 38 36 33 39 34 49 47 48 4 6 44 42 43 41 21 22 26 24 28 29 27 23

  • java 配列のソートについて

    JAVAを現在独学で勉強中ですが、わからないコードがあります。 プログラミングの先輩方、暇なときにでも教えてください。 for(int i=0; i<test.length; i++){ String str =br.readLine(); test[i] =Integer.parseInt(str); } for(int s=0;s<test.length-1;s++){ for(int t=s+1; t<test.length;t++){ if(test[t]>test[s]){ int tmp =test[t]; test[t] =test[s]; test[s]=tmp } } } 2回目のtest.length-1の-1はどういった役割を果たしてるんでしょうか? またjavaの構文の中でも、配列のソートがどうしても苦手です。 何かソートを理解するのにコツみたいなものがあれば、ご教授ください。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • javaのシェルソートについて質問です

    //Sample482 import java.util.Random; class Sample482{ static int shellSort1(int[] x){ int n = x.length; int cnt = 0; for(int h = n/2;h > 0;h /= 2){ for(int i = h;i < n;i++){ int tmp = x[i]; int j; for(j = i;j > h-1 && x[j-h] > tmp;j -= h){ cnt++; x[j] = x[j-h]; } x[j] = tmp; } } return cnt; } public static void main(String[] args){ Random rand = new Random(); int n = 20000; int[] x = new int[n]; for(int i = 0;i < n;i++){ x[i] = rand.nextInt(1000000); } int cnt = shellSort1(x); System.out.println("昇順にソートしました。"); for(int i = 0;i < n;i++){ System.out.println("x[" + i + "]=" + x[i]); } System.out.println("要素の移動回数" + cnt); } } //Sample483 import java.util.Random; class Sample483{ static int shellSort2(int[] x){ int n = x.length; int cnt = 0; int h; for(h = 1;h < n/9;h = 3*h+1); for(;h > 0;h /= 3){ for(int i = h;i < n;i++){ int j; int tmp = x[i]; for(j = i-h;j >= 0 && x[j] > tmp;j -= h){ x[j+h] = x[j]; cnt++; } x[j+h] = tmp; } } return cnt; } public static void main(String[] args){ Random rand = new Random(); int n = 20000; int[] x = new int[n]; for(int i = 0;i < n;i++){ x[i] = rand.nextInt(1000000); } int cnt = shellSort2(x); System.out.println("昇順にソートしました。"); for(int i = 0;i < n;i++){ System.out.println("x[" + i + "]=" + x[i]); } System.out.println("要素の移動回数:" + cnt); } } 上記のSample482とSample483はどちらもシェルソートを扱ったコードです。 参考書やネットの情報によると、後者のSmple483のシェルソートの方がより高速にソート することができるらしいのですが、実際に実行してみると、要素の移動回数は Sample482よりSample483の方が多くなります。 要素の移動回数が多いということは、それだけソートに時間がかかると私は思うのですが、 何故、後者のシェルソートの方が高速に動くといえるのでしょうか?

  • マージソート

    マージソートの実行時間を測定するプログラムを書いています。 コンパイルの時にはエラーが出ないのですが、実行するとコマンドプロンプトが強制終了されます。 どこが悪いか、どう直せばいいのか指摘していただけないでしょうか? よろしくお願いします。 ~qtime.c~ //マージソート実行用プログラム //bcc32 mtime.c merge.c m1.c sfmt.c #include <stdio.h> #include <stdlib.h> #include <time.h> #include "sfmt.h" #define MAX 5000 void merge_sort(int a[], int start, int end); main() { int i , x[MAX] , n; time_t start , end ; int sn; printf("適当な数字の入力 : "); scanf("%d", sn); init_gen_rand(sn); for(i=0; i<MAX; i++) x[i]= (gen_rand32()% MAX);; n=MAX; start = clock(); //測定対象プログラム merge_sort(x, 0, n-1); end = clock(); printf("sort\n"); for(i =0 ; i < n ; i++ ) if ( i == i/100*100) printf("%d\n" , x[i]); printf ("実行時間: %f sec\n" , (double)(end-start) /CLOCKS_PER_SEC); return 0; } ~merge.c~ int b[100]; void merge_array(int x[], int start, int end) { int mid, i, j, k; mid = (start + end) /2; i = start; j = mid + 1; for(k = start; k <= end; k++){ if(x[i] > x[j] && j <= end || i > mid){ b[k] = x[j]; j++; } else{ b[k] = x[i]; i++; } } for(k = start; k <= end; k++){ x[k] = b[k]; } } ~m1.c~ void merge_array(int x[], int start, int end); void merge_sort(int a[], int start, int end); void merge_sort(int a[], int start, int end) { int mid; if(start >= end) return; mid = (start + end) / 2; merge_sort(a, start, mid); merge_sort(a, mid + 1, end); merge_array(a, start, end); }

  • クイックソートのプログラムについて

    一から自分なりにやってみましたが、再帰処理の部分がうまくゆきません。 改善方法をご教授願えたらと思います。 #include<stdio.h>   void qsort (int x[], int a, int b) {  int temp, kijyun, i;  kijyun = a;  i = a + 1;  while (i <= b)   {    if (x[i] < x[kijyun])     {      change (x, kijyun, i);      kijyun = kijyun + 1;     }    i++;   }  if (kijyun != 0) //基準より左側をソートする。   {    qsort (x, 0, kijyun - 1);   } //以下if文の部分で、うまくいきません。  if (kijyun != 9) //基準より右側をソートする。   {    qsort (x, kijyun + 1, 9);   } } int change (int x[], int a, int b) //x[b]をx[a]の位置に挿入させる。 {  int i, temp;  i = b;  while (i != a)   {    temp = x[i];    x[i] = x[i - 1];    x[i - 1] = temp;    i--;   } } int main (void) {  int i, x[9] = { 6, 8, 9, 5, 3, 2, 1, 4, 7 };  qsort (x, 0, 8);  for (i = 0; i != 9; i++)   {    printf ("\n%d", x[i]);   } }

  • ソート

    読み込むファイル(sample.txt)は、 2,jirou 5,gorou 4,shirou 1,tarou 6,mutsuo 3,saburou 下記の処理をします。 #include<stdio.h> #include<string.h> #define N 6 int sort1[N]; char sort2[N][30]; int BubbleSort(int data[N]) { int i,j,flag; do{ flag=0; for(i=0;i<N-1;i++) { if(data[i]>data[i+1]) { flag=1; j=data[i]; data[i]=data[i+1]; data[i+1]=j; } } } while(flag==1); return 0; } int main(void) { FILE *fpin; int id,h,k; printf("\n"); fpin=fopen("sample.txt","r"); if(fpin==NULL){ printf("ファイルをオープンできず!\n"); return 1; } for(k=0;k<N;k++) { h=fscanf(fpin,"%d,%s",&sort1[k],sort2[k]); if(h==EOF) break; printf("%d %s\n",sort1[k],sort2[k]); } printf("\n"); BubbleSort(sort1); for(k=0;k<N;k++) printf("%d %s\n",sort1[k],sort2[k]); return 0; } 実行結果は、 2 jirou 5 gorou 4 shirou 1 tarou 6 mutsuo 3 saburou 1 jirou 2 gorou 3 shirou 4 tarou 5 mutsuo 6 saburou 名前(sort2)もソートさせるには、どうすればいいか手ほどきをお願いします…

専門家に質問してみよう