• ベストアンサー

バブルソートを入れたいのですが

こんにちは、Perlを始めたばかりの初心者です。 さっそく質問の方失礼します。 乱数1~100までの数字のうち20個をとりだし配列にいれ、数字を昇順に入れ替えして昇順前と昇順後の数字を表示する問題なのですが。 @a[100]=(1..100); srand(time()); for($i=0 ; $i<20 ; $i++){ $a=int(rand(@a)); print"$a\n"; } と上記の乱数20個を取り出すことができたのですが、 そのあとの昇順させようとしてバブルソートを利用したいのですが、どのように組み込めばいいかわかりません。 どのように組み込めばいいのでしょうか? お答えの方ヨロシクお願いします。

  • Perl
  • 回答数3
  • ありがとう数3

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

@a=(1..100); srand(time()); for($i=0 ; $i<20 ; $i++){ $before[$i]=$a[rand @a]; } @after = sort { $a <=> $b } @before; print "before:\n"; print join(",",@before) ; print "\nafter:\n"; print join(",",@after) . "\n";

terunosuke
質問者

お礼

お答えいただき有難うございます。 こちらが作ったものと比べるととても 綺麗にまとまっていたので驚かされました。 参考にさせて頂きました。 ありがとうございます。

その他の回答 (2)

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

@b = sort { $a <=> $b; } @a; で @a に入っている要素を数値として比較し, 昇順に @b に入れます. 文字列として比較したければ @b = sort { $a cmp $b; } @a; 降順だったら, 数値の場合には @b = sort { $b <=> $a; } @a; 文字列の場合には @b = sort { $b cmp $a; } @a; 一般には sort ブロック 配列 の形で, ブロックの部分は評価して数値になる必要があります. ブロックの中では特殊な変数として $a, $b を使います. 結果として得られる配列は, 前の方の要素を $a, 後ろの方の要素を $b としたときにこのブロックの返す値が 0 以下になるようなものとなります. 例えば { $a <=> $b; } というブロックだと, 最終的に得られる配列は ((前の方の要素) <=> (後ろの方の要素)) <= 0, つまり (前の方の要素) <= (後ろの方の要素) を満たすものになるので昇順にソートできる, ということになります.

terunosuke
質問者

お礼

参考にさせて頂きました。 解りやすい説明をありがとうございます。

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

どうしてもバブルソートでなければならないという特段の理由がない限りは sort を使うのが普通だと思います.

terunosuke
質問者

お礼

早速のアドバイスありがとうございます。 こちらの記入ミスがあったようで、すみません。 使用するのはバブルソート以外のものでもOKです。 ソートでのやり方を教えていただければ幸いです。

関連するQ&A

  • ソートを利用して文字を昇順で入れ替えしたいのですが

    こんにちは、日頃こちらではお世話になっております。 早速、質問で失礼します。 以前こちらで数字を乱数1~100の間の20個をとりだし昇順前と昇順後を表示させるやり方を教えてもらって、このプログラムを少し変えて 『乱数(AA,AB,AC...BA..BV..ZZ)を20個取り出す』 プログラムを作ろうとしていまして乱数の20個を取り出す所までいけたのですがその後の昇順で詰まってしまいます。 @ab=(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z); srand(time()); for($i=1;$i<=20;$i++){ $a=int(rand()*26); $b=int(rand()*26); $string = $ab[$a] . $ab[$b]; print "$string\n"; } この後に @after = sort { $a <=> $b } @before; print "before:\n"; print join(",",@before) ; print "\nafter:\n"; print join(",",@after) . "\n"; 入れるのはわかるのですが for(){    (1)     } の間にどう組み込めば良いのでしょうか? それと追加質問で申し訳ないのですが (1)自分で、英字を入力して、20個の数字から探すプログラムを作って、見つかった場合には、配列の何番目に入っていたかを出力。入っていない場合には、"見つかりません"と出力して、再度入力させる。 (2)20個の数字からD?(DA,DB,DC,DD,DE...DZ)の文字列をすべて抜き出しす。必ず正規表現を使用する。 上記のプログラムの作り方&解説等をお願い致します。 続けて質問して申し訳ありませんが宜しくお願いします。

    • ベストアンサー
    • Perl
  • クイックソートについて

    下記のソースプログラムのquick_sort_coreの部分がわかりません。 わかる方助けてください。 あとこのソースを降順にした場合の変更点も教えていただけると助かります。 #include <stdio.h> /* printf()利用のため */ #include <stdlib.h> /* rand()利用のため */ #include <time.h> /* clock()利用のため */ #define N 10 /* 整列対象要素数 */ /** * 配列の中身を表示する関数 * @param a 表示する配列 * @param n 配列の要素数 */ void print_array(const int a[], int n) { int i; for (i = 0; i < n; i++) { printf("%d ", a[i]); } printf("\n"); } /** * 整列されているかどうか確認する関数 * @param a 確認対象配列 * @param n 配列の要素数 */ void is_sorted(const int a[], int n) { int i; for (i = 0; i < n - 1; i++) { if (a[i] > a[i + 1]) { printf("昇順に整列されていません\n"); return; } } printf("昇順に整列されています\n"); } /** * クイックソートの本体 * @param a 整列対象配列 * @param l 対象の最初の要素番号 * @param r 対象の最後の要素番号 */ void quick_sort_core(int a[], int l, int r) { /* ここを実装する */ } /** * これまでの整列関数のインターフェースにあわせるクイックソート呼び出し関数 * @param a 整列対象配列 * @param n 配列の要素数 */ void quick_sort(int a[], int n) { quick_sort_core(a, 0, n - 1); } int main(void) { int i; int n = N; /* 整列対象要素数 */ int a[N]; clock_t start,end; /* 0からRAND_MAXの一様乱数をn個生成し、配列aに格納 */ for (i = 0; i < n; i++) { a[i] = rand(); /* 出力確認(print_array)するときは a[i]=rand()%100 としておくと見やすい */ } /* 昇順にソートされているか確認(デバッグ用) */ is_sorted(a, n); /* 配列の中身を確認(デバッグ用) */ print_array(a, n); /* 開始時刻の取得 */ start = clock(); /* クイックソート関数の呼び出し */ quick_sort(a, n); /* 終了時刻の取得 */ end = clock(); /* 配列の中身を確認(デバッグ用) */ print_array(a, n); /* 昇順にソートされているか確認(デバッグ用) */ is_sorted(a, n); /* 実行時間の表示 */ printf("%d 個の要素のクイックソートの実行に %f [秒]かかりました\n", n, (double)(end - start) / CLOCKS_PER_SEC); return 0; }

  • バブルソート

    int a[] = {8,45,15,90,62,73,22}をバブルソートを使用して、降順で並べ替える。 以下の説明では、配列の要素数(ここでは7)をNとしている。 (1) a[N-1] と a[N-2] を比較し、a[N-1] が a[N-2] より大きい場合は、a[N-1] と a[N-2] を入れ替える。   同様に a[ j] が a[ j-1] より大きければ、a[ j] と a[ j-1] を入れ替える。   この操作を、j=N-1からiまで繰り返す。ただし、iは(1)の処理回数を表す値である。(初回を0とする) (2) (1)を i=0 から N-2 まで繰り返す。 (3) 以下の<実行例>を参考に、配列aのようその各値を標準出力する。 <実行例> 90 73 62 45 22 15 8 という問題なのですが、どうやってもうまく並び替えられません。 a[N-1] の処理はいらないのではないのですか? どのようにプログラムを書いたらいいのか教えて下さい。 あつかましいですが、できたら解説付きでお願いします。

    • ベストアンサー
    • Java
  • バブルソート、あなたはどちら派?

    昇順にソートする場合ですが、 配列の先頭とその次の値を比較し、大きい数字の方を後ろへ持っていくパターンと 配列の最後とその手前を比較し、小さい数字を前へ持っていくパターンがあると思います。 前者のほうが、湖底から水面へ泡がだんだん大きくなっていくバブルのイメージで 長年これがスタンダードだと思っていたのですが、 後者についてを「小さい泡がだんだん移動していくイメージなのでバブルソートと言う」と 断言しているサイトや書籍もあります。 どちらも間違いではないと思います。 ですが、他人に教えることを想像したとき、 どちらかというと先に前者を教えてから、後者のやり方もあるよと伝えた方が 直感的に理解しやすいかなと思いました。 皆さんはどちら派ですか? また、前者と後者を使い分けるメリットがもしもあればご教示頂けませんか?

  • java(バブルソート/単純挿入ソート)

    以下のプログラムを「バブルソートもしくは単純挿入ソートのプログラムに変更しなさい」という課題が出ました。 どのようにすればよろしいでしょうか? import java.util.*; public class SelectSort { //プログラムクラス名 //整列プログラム public static void main(String[] args){ //整列用 int 型配列 int[] target; int elems = KeyboardInput.askInt("要素数? "); //配列を乱数で初期化する target = setArray(elems); //初期状態を表示 display(target); //整列メソッドの呼び出し sortArray(target); //整列結果の表示 display(target); } //配列を乱数で初期化するメソッド static int[] setArray(int elems){ // 要素数個の int 型変数の確保 int[] array = new int[elems]; //乱数利用ための宣言 Random generator = new Random(); //乱数の最大値・最小値 int max = 100; int min = 0; //generator.nextDouble() で 0から1までのdouble型乱数発生 for(int i=0 ; i<array.length ; i++) { array[i] = (int)((max-min)*(generator.nextDouble())+min); } return array; } //配列の状態を表示 static void display(int[] array){ for(int i=0 ; i<array.length ; i++) { System.out.print(array[i]+" "); } System.out.println(""); } static void sortArray(int[] array){ //配列のはじめから最後まで繰り返す for( int i = 0; i < array.length-1 ; i++){ int min_id = i; int min = array[i]; //範囲中でもっとも小さい要素を探す for( int j=i+1 ; j< array.length ; j++ ) { if( array[j] < min ){ min = array[j]; min_id = j ; } } //範囲の始めと置き換える int tmp = array[i]; array[i] = array[min_id]; array[min_id] = tmp; //display(array); } } }

  • クイックソートの処理速度に関する実験 要素1万個、

    クイックソートの処理速度に関する実験 要素1万個、2万個、3万個の配列変数にランダムな値を代入し、・その後クイックソートで小さい順に並べ替える #include<stdio.h> #include<stdlib.h> #include<time.h> #define ASIZE 10000 #define RAND_SEED 0x1131000 void my_sort(int left, int right, int a[]); int main(void){ clock_t start, end; int i,a[ASIZE]; srand(RAND_SEED); for(i=0;i<ASIZE; i++){ a[i]=rand(); } start=clock(); my_sort(0, ASIZE-1, a); end=clock(); printf("%.3f秒でした" ,(end-start)/(double)CLOCKS_PER_SEC); getchar(); return 0; } void my_sort(int left, int right, int a[]){ ここに入れるプログラムがわかりません return; }

  • バブルソートで並べ替え

     学校でC言語入門をやっています。今回「バブルソート」で配列の要素を降順(大きい順)に並べ替えるということをやっています。  バブルソートの原理はわかりましたが、書き方がよくわかりません。まず簡単な配列として、a[5]={5,2,24,8,31} というものを考えています。    for(k=0;k<n-1;k++){ if(a[k]<a[k+1]){ t=a[k];a[k]=a[k+1];a[k+1]=t; } } とすると、全範囲の中でバブルソートをおこなうので一番小さい"2"が a[4] に入り、位置の確定ができます。  今度は確定していない範囲でバブルソートをおこなうと for(m=0;m<k;m++){ if(a[m]<a[m+1]){ t=a[m];a[m]=a[m+1];a[m+1]=t; } } と先ほどと同様に書け、この中で一番小さい"5"が a[3] に確定します。以下同様に、範囲をせばめていきあと2つ for文を書くと全ての要素の位置が確定することになりますが、これは要素の数が多くなるととても大変なので複数の for文を1つのfor文でまとめたいのですがよくわかりません。  あと、バブルソートには上と下から(左と右から)の両方から査定する「カクテルシェイカソート」というものもあるらしいのですが、今回は一方向からの査定でやるという指示なのでよろしくお願いします。

  • 乱数について

    Visual Studio2008を使っています。 #include<stdio.h> #include<stdlib.h> #include<time.h> int main(void){ int i; srand(time(NULL)); i=rand(); printf("%d\n",i); return 0; } 乱数を作るために上のようなプログラミングを作りました。 これを「ソリューションのビルド」すると 【warning C4244: '引数' : 'time_t' から 'unsigned int' への変換です。データが失われる可能性があります。】 と出ます。 このまま行っても乱数が出来るのですが どうしたらいいのでしょうか? 8行目を srand(time_t(NULL)); srand((unsigned)time(NULL)); と変えればいいのでしょうか? time_tでやると乱数が同じ値しか出てきません。 教えてください。

  • 主キーソート(キーの優先順位をつけてソート)

    時刻から生成した乱数を、構造体「TEST」のメンバ変数 a, b, c に代入し、 メンバb を基準にして、昇順にクイックソートしてみます。 #include <stdio.h> #include <stdlib.h> #include <time.h> typedef struct{ int a; int b; int c; }TEST; int comp( const void *c1, const void *c2 ); int main(void) { int i; TEST base[10]; /* 乱数の生成 */ srand( (unsigned int)time( NULL ) ); for( i=0; i<10; i++ ){ base[i].a = rand() % 100; /* 0~99の乱数 */ base[i].b = rand() % 100; base[i].c = rand() % 100; printf( "%d¥t", base[i].a ); printf( "%d¥t", base[i].b ); printf( "%d¥t", base[i].c ); printf( "¥n" ); } /* TEST構造体のbを基準にソート */ printf( "¥n--TEST構造体のbを基準にソート--¥n¥n" ); qsort( base, 10, sizeof(TEST), comp ); /* ソート後のデータを表示 */ for( i=0; i<10; i++ ){ printf( "%d¥t", base[i].a ); printf( "%d¥t", base[i].b ); printf( "%d¥t", base[i].c ); printf( "¥n" ); } return 0; } /* 比較関数 */ int comp( const void *c1, const void *c2 ) { TEST test1 = *(TEST *)c1; TEST test2 = *(TEST *)c2; int tmp1 = test1.b; /* b を基準とする */ int tmp2 = test2.b; return tmp1 - tmp2; } ランダム結果 13 22 21 63 21 45 52 45 81 75 67 94 7 1 44 81 66 38 35 24 35 62 6 4 76 12 84 86 77 71 --TEST構造体のbを基準にソート-- 7 1 44 62 6 4 76 12 84 63 21 45 13 22 21 35 24 35 52 45 81 81 66 38 75 67 94 86 77 71 と、このように表示されます。 下段の真ん中の列を見ると、メンバ変数 b で並び替えられている事が分かります。 比較関数comp内では、TEST構造体でキャストしてから、bを取り出しています。 また、戻り値に「tmp1 - tmp2」を使うことで、 「a < b :負の値、a == b :0、 a > b :正の値」という条件に当てはめています。 とhttp://simd.jugem.jp/?eid=116で書かれていますが これはb列を基準にしたソートであり、a列とc列の優先順位は書かれていません キーの優先順位をb>a>cにするにはどうしたらよいでしょうか。 もっとたくさんキーあった時(a>b>c>d>e>f>g・・・)のようにキーの優先順位つけて昇順or降順にデータをソートしたいです。 よろしくお願いします

  • 乱数の取得

    キー操作をした時に複数の乱数を習得させようと思っています。 【キ─操作関数】  int num[3] = {11, 22, 33}; ←初期化のため数字は適当です。  srand((unsigned int)time(NULL))  for(int i=0; i<=3; i++)  {   num[i] = rand % 10;  } 上記のプログラムを書いています。 num[0]、num[1]、num[2]にそれぞれ0~9の乱数が入ると思うのですが、 num[0]にしか乱数が入りません。 num[1]、num[2]には同じ数字(恐らくtimeで取得した数字?)が入っています。 何かお気づきの点がありましたらアドバイスお願い致します。

専門家に質問してみよう