• 締切済み

クイックソート

振り仮名でソートをしたいのですが不等号の「<」など記号など混ぜた時にうまくソートされません。 ロジック的に問題があると思うのですが、平仮名や全角カタカナはソートされてるのです。以下のソースなのですが分かる方ご指摘頂ければ幸いです。 int lo0は固定で0 int hi0は検索結果の数-1となっております。 getKana()は振り仮名をbeanから取得しています。 private void QuickSort(Vector beanValues, int lo0, int hi0) { int low = lo0; int high = hi0; String mid; Object[] records = beanValues.toArray(); if (hi0 > lo0) { mid = ((Bean)records[ ( lo0 + hi0 ) / 2 ]).getKana(); while( low <= high ) { while ((low < hi0) && (((Bean)records[low]).getKana().compareTo(mid) < 0)) { ++low; } while ((high > lo0) && (((Bean)records[high]).getKana().compareTo(mid) > 0)) { --high; } if (low <= high) { swap(beanValues, low, high); ++low; --high; } } if (lo0 < high) QuickSort(beanValues, lo0, high); if (low < hi0) QuickSort(beanValues, low, hi0); } } private void swap(Vector records, int i, int j) { Object T = records.elementAt(i); records.setElementAt(records.elementAt(j), i); records.setElementAt(T, j); } }

  • Java
  • 回答数2
  • ありがとう数0

みんなの回答

回答No.2

可能性として「Y」と「<」が全角ならばそのようなソート結果になるかとおもいますが、その辺の可能性はないですか?

shinchun
質問者

補足

2つ共半角でした。 付き合って頂いてありがとうございます。 新規でデータを登録すればきちんと認識されるのですが移行データだけがそのようなおかしなものになるので厄介でして・・・・。

回答No.1

compareToメソッドの返り値はUnicodeの辞書式順なのですが、これがshinchunさんの望んだ並び順と異なるためではないでしょうか? http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/lang/String.html#compareTo(java.lang.String) http://ja.wikipedia.org/wiki/Category:Unicode%E8%A1%A8

shinchun
質問者

補足

回答ありがとうございます。 Unicode表で番号を全て比較したのですがどうしてもおかしくて。。。 ちなみに検索結果が出る頭の文字は以下の順です。 頭文字:Unicode (:0020 8 5:0030 5 C:0040 3 C:0040 3 N:0040 E <:0030 C Y:0050 9 <の位置がなぜかそのようなとこに・・・・。 <のデータは<----と続いており<を省いても同じ検索結果になりました。

関連するQ&A

  • クイックソート

    クイックソートのプログラムを作ったのですがうまくいきません 汗 コンパイル時に sample1.c: In function ‘quicksort’: sample1.c:31: error: expected expression before ‘]’ token sample1.c:32: error: expected expression before ‘]’ token sample1.c:32: error: too few arguments to function ‘quicksort’ とでます。 まだアルゴリズムやCは勉強始めたばかりで基本的なところでつまって いるかもしれません。ご教授おねがいします。 /*クイックソート*/ #include<stdio.h> #define MAXDATA 10 #define swap(type,a,b) {type m; m = a; a = b; b = m;} void quicksort(int a[],int left ,int right) { int i,j,pivot; pivot = a[left]; i = left + 1; j = right; while(i <= j){ while(a[i]<pivot) i++; while(a[j]>pivot) j--; if(i<j){ swap(int,a[i],a[j]); i++; j--; } } swap(int,a[left],a[j]); quicksort(a[],left,j-1); quicksort(a[],j+1,right); } int main(void) { int k,j,sort[MAXDATA]; for(k=0;k < MAXDATA;k++) {printf("sort[%d]:",k); scanf("%d",&sort[k]);} for(k=0;k < MAXDATA;k++) printf("%3d",sort[k]); puts("ソートしますか? Yes:1 No:0 ///"); scanf("%d",&j); if(j==1){ quicksort(sort,0,MAXDATA-1); for(k=0;k < MAXDATA;k++) printf("%3d",sort[k]); } putchar('\n'); return(0); }

  • マージソートについて

    マージソートの要素の比較と交換回数を計測するプログラムを作っているのですが、マージのどの段階が交換処理になるのかが分からず困っています。 マージ処理の実行回数をカウントする配列sを設けて処理をカウントする場合、以下のプログラムだとどのタイミングでカウントすればよいでしょうか? ちなみに配列aは初めに値を割り振った配列で、配列bは別途で用意した作業用配列です。 最後のfor文やif文付近で配列の値を変化させて計測してみたのですが、計算量に合った動きをしてくれませんorz void merge_sort(int a[], int low, int high){ int mid, i, j, k; if(low >= high) return; mid = (low + high)/2; merge_sort(a, low, mid); merge_sort(a, mid+1, high); for(i = low; i <= mid; i++) b[i] = a[i]; for(i = mid+1, j=high; i <= high; i++, j--) b[i] = a[j]; i = low; j = high; for(k = low; k <= high; k++){ if(b[i] <= b[j]){ a[k] = b [i++]; } else{ a[k] = b[j--]; } } }

  • クイックソート

    今クイックソートのプログラム作成をしていますが、分からない箇所が幾つかあります。下は、作成した時のプログラムリストです。 class QuickSort{ static int compare = 0;   static int copy = 0;    static int swap = 0; static void swap(int a[], int i, int j){    int tmp; tmp = a[i];copy++; a[i] = a[j];copy++; a[j] = tmp;copy++; swap++;} static void showArray(int a[], int l, int r){//配列の内容を表示するメソッドで、動作:部分配列a[l]~a[r]の要素を表示。これが分かりません。     int a[l] = {1,2,3,4,5,6,7,8,9,10}; int a[r] = {11,12,13,14,15,16,17,18,19,20};} static void initArray(int a[], int N){ int i;     a[0]=0; for(i=1;i<N;i++) a[i] = i; for(i=1;i<N;i++){ int j,k; j = (int)(java.lang.Math.random()*(N-1)) + 1; k = (int)(java.lang.Math.random()*(N-1)) + 1; swap(a,j,k);}} public static void (int a[],int l, int r) { if (r+1-l <= 1) return; int e = (l+r+1)/2; int c = 0; return a[c]; } static int partition(int a[], int l, int r, int pivot){// 配列の分割を行うメソッドです。そのあと分割に要した比較回数(=iの増加分+jの減少分)を変数compareに加算し、iの値を戻り値として返さないといけませんが、そこんとこが分かりません。 while (true) { while (a[l] < pivot) l = l + 1; while (a[r] >= pivot) r = r - 1; if (l > r) return l; swap(a, l, r); } } static void swap(int[] a, int i, int j) { int tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } int i=0; int j=0; return i; } static void quicksort(int[] a, int l, int r){//(カットオフなしで)再帰的にクイックソートを行うメソッドです。paritionメソッドを用い、a[l]~a[r]を分割値a[r]で分割するのが条件ですが、ここも全然分かりません。 if(l < r){ int i = l; int j = r; int x = a[(i+j)/2]; do{ while(a[i]<x) i++; while(a[j]>x) j--; if(i<=j) { swap(a,i,j); i++; j--; } }while(i<=j); quickort(a,l,j); quicksort(a,i,r); } } static void swap(int[] a, int s, int t){ int temp = a[s]; a[s] = a[t]; a[t] = temp; return; int i,pivot; } public static void main(String args[]){ //上で作ったメソッドを用いて、ソート過程を表示しながらクイックソートを実行 //手順は次のようになる。     1.要素を(20個もつ)整数型配列aを宣言     2.整数型変数Nに配列aの要素数を保存     3.initArrayメソッドを用いて配列aを初期化 4.showArrayメソッドを用いてソート前の配列aの内容を表示 5.変数compare,copyの値を0に初期化 6.quickSortメソッドを用いて配列aを選択ソート     7.showArrayメソッドを用いてソート後の配列aの内容を表示 8.ソートにかかった比較・コピーの回数を表示 //これも分かりません。 } 分かる人がいましたら教えて下さい。お願いします。

  • while文の判定について(C言語)

    while文の判定についてです たぶんすごいつまらないミスなので時間の余っている方 ご指導ください<_ _> (自分ではいろいろ調べましたが原因がわかりません><、) returnやbreakを使わないで二分探索を終了させよとの問題で low-highで2ならばデータが見つかったとき 1ならば見つからなかったときという判定で whileで抜けさせたいのですがどうしても抜けません><、 論理演算子の使い方が間違っているのでしょうか? #include<stdio.h> #define N 10 int main(void) { static int a[]={2,3,4,11,31,50,55,70,77,80}; int key,low,high,mid; high=N-1; low=0; int i=0; printf("検索するdata ? :");scanf("%d",&key); ここです while((2!=(low-high)) || (1!=(low-high))){ mid=(low+high)/2; if(a[mid]==key){ low=mid+1; high=mid-1; } else if(a[mid]<key){ low=mid+1; } else{ high=mid-1; } } if(2==(low-high)){ printf("%2dは%2d番目にありました",key,mid); } else{ printf( "見つかりませんでした" ); } return 0; } while内でlow-highをprintfで出力しましたが2と1が出力されました

  • クイックソートについて

    クイックソートのプログラムなんですが、 セグメンテーション違反で実行出来ません。 どこがおかしいのでしょうか? int main(void) { FILE *fp; int a[10],b=0,n; clock_t start; double jikan; if( (fp = fopen ("quicksort.txt","r") ) == NULL ) { printf("ファイルが見つかりません : quicksort.txt\n"); exit(1); } while( fscanf(fp, "%d", &a[b]) != EOF ) { b++; } start = clock(); quick_sort(a,n); jikan = clock() - start; for(n = 0; n < b ; ++n) { printf("%d ",a[n]); } printf("計算時間 %.3f 秒 \n", jikan/CLOCKS_PER_SEC); return 0; } int partition(int a[], int l, int r) { int i,j,pivot,t; i = l-1; j = r; pivot = a[r]; for(;;) { while( a[++i] < pivot ) ; while( i < --j && pivot < a[j] ) ; if( i >= j ) break; t=a[i]; a[i]=a[j]; a[j]=t; } t=a[i]; a[i]=a[r];a[r]=t; return i; } void quick_sort_1(int a[],int l,int r) { int v; if( l >= r ) return; v = partition( a, l, r); if( l < v-1 ) quick_sort_1( a, l, v-1); if( v+1 < r ) quick_sort_1( a, v+1, r); } void quick_sort(int a[],int n) { quick_sort_1( a, 0, n-1); }

  • c言語のクイックソートなんですが・・・

    以下のプログラミングなのですが、***のところが分かりません。 どなたか教えていただけないでしょうか? (よろしければ、前後の必要なところも書いていただけると幸いです) void quicksort(int l, int r) { int i,j,p,w; i=***; j=***; p=a[(int)((l+r)/2)]; while(i<=j) { while(a[i]<p) i++; while(p<a[j]) ***; if(i<=j) { w=a[i];a[i]=a[j];***; i++;***; } } if(l<j) quicksort(l,j); if(i<r) ***; }

  • クイックソートがうまくいかない

    クイックソートとはこういう仕様のソートのことです。 (1)バラバラの配列から基準値を設定する。 (2)前から順番に辿って行って基準値よりも大きいならば、基準値よりも後に移動、小さいならば、基準値よりも前に移動させる。(私のプログラムの場合は基準値を配列の一番目の数に設定しています。) (3)小さいほうと大きいほうの二つのグループに分かれたらまたそれらのグループごとにクイックソートにかける。 (4)二つのグループを分けることができなくなればソート完了。 自分で確かめてみたのですが、どうやら関数QuickSortの中でさらに再帰的にQuickSortにかけるときにバグが発生しているようです。ですが、なぜバグが起きるのかわかりません。 お手数ですが、よろしくお願いいたします。 #include<stdio.h> #include<stdlib.h> #include<time.h> #include<string.h> #define N 10 void QuickSort(char mi,char *hai,int youso) { char *shoubox; char *bigbox; int k=0; int q=0; int i,len,len2; /*もし配列haiの大きさが1ならば終了*/ if(strlen(hai)==1) { return; } /*配列の2番目から最後まで基準値からの大小により仕分けしていく。大きいならば、配列bigboxに小さい*/ /*ならば配列shouboxにそれぞれ入れる。*/ for(i=1;i<youso-1;i++) { if(hai[i]>mi) { bigbox[k++]=hai[i]; } else { shoubox[q++]=hai[i]; } } /*仕分け処理はここまで*/ /*小さいほうの配列と大きいほうの配列をそれぞれクイックソートにかける再帰処理。*/ QuickSort(shoubox[0],shoubox,q); QuickSort(bigbox[0],bigbox,k); /*それぞれのソートが完了したら、配列haiに「小さいほうの配列」→「基準値」→「大きいほうの配列」 の順に値を代入していく。*/ len=strlen(shoubox); for(i=0;i<len;i++) { hai[i]=shoubox[i]; } hai[len]=mi; len2=strlen(bigbox); for(i=(len+1);i<len+len2;i++) { hai[i]=bigbox[i]; } /*代入処理ここまで。*/ } int main(void) { char array[N]; char m; int i,val,j; srand(time(NULL)); /*(1~10)までの数字をランダムに入力する処理*/ for(i=0;i<N;i++) { do{ val=rand()%10; for(j=0;j<i;j++) { if(val+'0'==array[j]) { break; } } }while(j<i); array[i]=val+'0'; } /*ランダムに値を入力する処理ここまで*/ m=array[0]; /*値配列の最初を基準値mに設定*/ QuickSort(m,array,N); /*基準値、配列、要素数を実引数として、クイックソートを呼び出す。*/ /*昇順に並べ替えた配列arrayを出力する。*/ for(i=0;i<N;i++) { printf("array[%d]=%c\n",i,array[i]); } return 0; }

  • C言語のクイックソートについて

    下記のようなクイックソートのプログラムをコーディングしたのですが、比較回数・挿入回数・シフト回数をそれぞれ知りたいのですが、どこにそれぞれのカウンタを挿入すればよいでしょうか? よろしくお願いします。 void quick(int a[],int left,int right) int i; int pl=left; int pr=right; int pivot; int tmp; pivot=a[(pl+pr)/2]; do{ while(a[pl]<pivot) { pl++; } while(a[pr]>pivot) { pr--; } if(pl<=pr) { swap(&a[pl],&a[pr]); pl++; pr--; } } while(pl<=pr); if(left<pr) { quick(a,left,pr); } if(pl<right) { quick(a,pl,right); } } void swap(int *x,int *y) { int temp; temp=*x; *x=*y; *y=temp; }

  • クイックソートの解説頂けないでしょうか。

    C言語を始めたばかりのプログラマ見習いです。 クイックソートのトレースでつまっています。 下記プログラムにあたっているのですが、 どなたか解説頂けないでしょうか。 void q_sort(int d[],int left,int right) { int i=left; int j=right; int t; t=d[(i+j)/2]; while(i<j){ for(;t>d[i];i++) ; for(;t<d[j];j--) ; if(i<=j){ /*Swap*/ int t; t=d[i]; d[i]=d[j]; d[j]=t; i++; j--; } } if(left<j){ q_sort(d,left,j); } if(){ q_sort(d,i,right); } } 長い引用で申し訳ありません。 クイックソートの理論的な部分は理解しているつもりです (最初に基準値を置き、それより大きいもしくは小さい 値を左右に振り分ける→分割統治法で繰り返し、最終的に 値がソートされた状態になる)。 よく判らないのがwhile文の中、特に最初のfor文の 役割です。初期値が空文で、中身もなし・・・この文は なにをしているのでしょうか? ネット上で解説されているソースをのぞいてみましたが 少し形が違っていたので、できればこのプログラムを もとにアドバイス頂けないでしょうか。 それ以外の回答(参考URL等)でも嬉しいです。 どうぞ宜しくお願いします

  • クイックソートのプログラムを実行するとエラーが出る

    プログラミング初心者のものです。 ソースのファイル名はquicksortという名前にして、コンパイル&実行すると、 「Quicksortが原因でQUICKSORT.EXEにエラーが発生しました。Quicksortは終了します。問題が解決しない場合は、コンピュータを再起動してください。」 と、 「Quicksortが原因でKERNEL32.DLLにエラーが発生しました。Quicksortは終了します。問題が解決しない場合は、コンピュータを再起動してください。」 と言うエラーが出てきて最後まで実行されません。 どうしてでしょうか?ちなみにソースは以下のものです。 #include<stdio.h> #define N 10 void quicksort(int a[],int first,int last) { int i,j,p,w,k; k=(first+last)/2; p=a[k]; i=first; j=last; while(i<=j){ while(a[i]<p){ i++; } while(a[j]>p){ j--; } w=a[i]; a[i]=a[j]; a[j]=w; i++; j--; } if(first>j){ quicksort(a,first,j); } if(last>i){ quicksort(a,i,last); } } main() { int a[]={18,97,59,72,5,38,11,43,67,26}; int i; printf("Before:"); for(i=0;i<N;i++){ printf("%4d",a[i]); } printf("\n"); quicksort(a,0,N-1); printf("After:"); for(i=0;i<N;i++){ printf("%4d",a[i]); } printf("\n"); return(0); }