dポイントプレゼントキャンペーン実施中!

よろしくお願いします。

100個の数字から20個の数字を重複なしで抽出したいと思っております。

以下、悪戦苦闘して作成したphpなのですが、重複が目立ちます。
array_unique関数を使用してみたのですが、どうも上手く行かない上体です。

お分かりになる方、是非ご指導下さい。

<?php
for ($i=0; $i<20; $i++) {
$num = mt_rand(0,100);
echo "$num";
echo "<br>\n";
}
?>

以上、よろしくお願いします。

A 回答 (7件)

ちょっとしたサンプルです。



<?php
$array = array();
for ($i = 0; $i < 20; $i++) {
  $num = mt_rand(1, 100);
  for ($j = 0; $j < $i; $j++) {
    // 配列に格納済の乱数と一致するか?
    if ($num == $array[$j]) {
      break;
    }
  }
  // 配列に格納済の乱数と一致していれば、再挑戦する
  if ($j < $i) {
    $i--;
    continue;
  }
  // 初登場の数値ならば、配列に格納する
  else {
    $array[$i] = $num;
  }
}

for ($i = 0; $i < 20; $i++) {
  print $array[$i] . "<br />";
}
?>

(注)インデントのため、全角空白を使っています。
    • good
    • 0

<?php


$numbers = range(1, 100);
shuffle($numbers);
for ($i = 0; $i < 20; $i++) {
echo $numbers[$i] . "<br>\n";
}
?>

参考URL:http://jp2.php.net/shuffle
    • good
    • 0

いくつかのやり方がありますが、PHPならshuffle関数がありますし汎用性を考えて次の様なやり方を考えてみました。



<?php
for ($i=0; $i<100; $i++) {
$uni_rand[i] = i; // 0-99の場合。1-100にするときは、 = i を = i+1 に
}

srand(microtime()*10000000); //乱数初期化。PHP4.2.1以降は不要
shuffle($uni_rand); //0-99の$uni_randをシャッフルする

for ($i=0; $i<20; $i++) {
echo $uni_rand[i]."<br>\n"; //シャッフルした$uni_randを順に必要数表示
}
?>
    • good
    • 0

$j=99;


$array = range(0,$j);
for($i=0;$i<20;$i++){
$rand = mt_rand(0,$j);
$num=$array[$rand];
$array[$rand]=$j;
$j--;
echo $num;
echo '<br>';
}
    • good
    • 0

重複無し、と言う条件なら、その条件をしっかり入れるべきです。

質問者さんのスクリプトでは単にランダムで引き出しているだけですよね。
こんな感じでしょうか。
<?php
$c = 0;
$a = array();
while ($c < 20) {
$num = mt_rand(0,100);
if(! array_search($num,$a)){
$a[] = $num;
$c ++;
}
}
$str = implode("<br />\n",$a);
echo $str;
?>
とりあえず配列にいれておいて、その配列の中に重複が無ければ追加します。20個でループを抜け、配列を改行キーを挟んで文字列に変換して出力しています。
    • good
    • 0

私なら、まず100までの配列を用意して、それをランダムに並べ替えた後、先頭の20コを表示、というふうに作ります。



<?php
for ($i=0; $i<100; $i++) $nums[$i] = $i+1;
for ($i=0; $i<100; $i++) {
$j = mt_rand(0,99);
$tmp = $nums[$j];
$nums[$j] = $nums[$i];
$nums[$i] = $tmp;
}
for ($i=0; $i<20; $i++) {
$num = $nums[$i];
echo "$num";
echo "<br>\n";
}
?>
    • good
    • 0

乱数を発生する目的を書かないと、適切なアドバイスができません。


乱数は乱数なのですから、以前に発生した乱数と同一の数字が出てくるのは、別におかしなことではありませんから。
さいころを振っても、同じ目が連続して出るのはそれほど珍しい現象ではありませんよね。

重複がいやなら、今まで発生した乱数を配列に格納しておいて、新しい乱数を発生させたときにそれと重複したら、再度乱数を発生する(手を抜くなら、単に1足すとか)ようにすればよいでしょう。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!