2011年06月08日

[C言語] ランダムな順列を出力する

 0〜5の6通りの値から重複のないように、かつランダムに数字を3つ選び、選んだ順番に表示します。

 これを実装するときに難しいのは、どうやって重複を避けるかということです。単純に0〜5の6通りの値を3回乱数で選んでしまうと、もちろん一定確率で重複する数字が出てくるので目的の機能を実現できません。過去に出現した値を記憶しておいて、乱数で選んだ数字が重複していたら選び直す……という方法も可能ですが、重複したときに無駄な感じがします。

 これから紹介する方法は、「表示できる候補」を配列の中に格納しておき、数字を1つ表示するたびにその数字を配列から削除するというものです。この方法の概要を次の図に示します。
Permutations.png

 図に出てきた変数を解説していきます。まず、iはループ変数で、1件出力するたびに1増えていきます。ここでは3桁出力するので0〜2の値をとることになります。patternsは、初期状態における表示可能な候補数です。ここでは0〜5の6通りですから、常にpatterns==6となります。stockは出力できる値の候補を格納しておく配列です。1度出力した値はもう出力できないのでstockから削除していきます。stockに格納されている値のうち、先頭からpatterns-i個のみが出力可能です。最後に、indexは、stockの何番目の値を出力するかを表す変数で、この値は乱数で決まります。

 ソースコードは次の通りです。実行すると、3桁の順列が出力されます。
人気ブログランキング

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
  int i,j;
  int patterns=6; /* 6通りの数字を表示 */
  int stock[]={1,2,3,4,5,6}; /* この中の数を表示 */
  
  srand(time(NULL)); /* ランダムにする。 */
  for(i=0; i<3; i++)
  {
    /* stockの何番目か決める */
    int index=rand()%(patterns-i);
    /* index番目を出力 */
    printf("%d",stock[index]);
    /* 出力した値はstockから削除 */
    for(j=index; j<patterns-1; j++)
      stock[j]=stock[j+1];
  }
  return 0;
}
web拍手 by FC2
【C言語の最新記事】
posted by 北条利彦 at 23:52 | Comment(1) | TrackBack(0) | C言語 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
出力した値はstockから削除・・・ということで配列の中身を寄せてますが、これだと手間かかりますよね。
選んだところと、最後からi番目を入れ替えると一回の操作で済むので早いですよ。
具体的にはstock[index]とstock[patterns-i-1]です。
Posted by とおりすがり at 2013年07月02日 06:33
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。