
$loop = 5;
$count = 0;
while($count < $loop){
mt_srand(microtime() * 100000);
$rand_key = rand(0,9);
if (in_array($rand_key, $yomi)){
$count--;
continue;
}
echo $yomi[$rand_key]\n;
}
配列($yomi)に格納されたひらがなから5つ重複させずに選び出したいのですが、
randで選出された「りんご」が2度選び出された場合、これでやり直しされますか?
現在出力出来る環境がありません…
初心者ですので指摘やアドバイス等いただけると嬉しいです。
よろしくお願いします。
No.1ベストアンサー
- 回答日時:
全然ダメですね。
まず、終了条件をみたすことがないのでこのプログラムは終了しません。
$count < $loopが終了条件ですが、$count--はあっても$count++が無いので、このプログラムは終了条件をみたすことはありません。(まあ、あえてあるとしたらinteger overflowで符号が逆転した時でしょうが...)
終了条件という点で言うと、重複を許さず選択するということなので$loopよりも$yomiの要素数が少ないと無限ループに陥るのでそのチェックをしたほうがベターです。
また、in_arrayの使い方もおかしいです。
上記のin_arrayでは$rand_keyが$yomiに含まれるか調べていますが、調べるべきは$yomiではなく既に選ばれたかどうかでしょう。その場合も$count--するのは間違っています。
さらに、この方向でプログラムを書くとしたら、次の2点を満たしてないとダメですね。
1. $rand_keyが使われたことを示す配列を作る
2. 表示した時だけ$countの値を増やす。選ばなかったらカウントアップしなければいいだけなので、$countから値を引く必要は全くないと思います。
あと、細かいことですがmt_srandの使い方も変です。PHP 4.2.0以降ではmt_srandは不要になりましたし、mt_srandを使うなら、乱数を取り出すにはmt_randだと思います。
http://php.net/manual/ja/function.mt-srand.php
という点を考えて書きなおすとこんな感じです。
if (count($yomi) > $loop) {
$selected_keys = array();
while ($count < $loop){
$rand_key = mt_rand(0, count($yomi) - 1);
if (in_array($rand_key, $selected_keys)) {
continue;
}
array_push($selected_keys, $rand_key);
$count++;
echo $yomi[$rand_key]."\n";
}
} else {
echo "Error: cannot choose yomi for $loop times.\n";
}
選択した$rand_keyは$selected_keysに入れておき、後でチェックしています。また、mt_randは端点を含むのでcount($yomi) - 1となっています。ちなみに、countとは配列の要素数を数える関数です。
http://php.net/manual/ja/function.mt-rand.php
http://jp1.php.net/manual/ja/function.count.php
元のやつだとn個からn個の要素を取る場合でnがある程度大きいと、何度も次のところを実行して空振りし続けるので、自分だったら別のやり方でやります。
| $rand_key = mt_rand(0, count($yomi) - 1);
| if (in_array($rand_key, $selected_keys)) {
| continue;
| }
$loopが要素数以上かのチェックは省略しました。$yomiのコピーを作って、出力するたびにそれを配列から消していきます。これだとそもそも配列には前回選んだものは含まれないのでin_arrayのチェックをする必要はありません。
$yomi_copy = $yomi; // make clone of $yomi.
for ($count = 0; $count < $loop; $count++) {
$rand_key = mt_rand(0, count($yomi_copy) - 1);
echo "$yomi_copy[$rand_key]\n";
array_splice($yomi_copy, $rand_key, 1);
}
ちなみに、PHPでは配列を代入すると配列のコピーができるので、$yomi_copyをいくらいじっても元の$yomiには影響を与えません。
また、array_spliceというのは配列の一部の要素を切り取る命令です。
http://php.net/manual/ja/function.array-splice.php
お早い回答ありがとうございます。
加算するのは忘れてました!
色々と勉強不足ですみません…
回答してくださったものを元にやってみます!
ありがとうございました!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
phpのheader("Location:#pos")...
-
PHP8でWarning:Undefined varia...
-
フォームで戻った際に入力済み...
-
csvファイルについて教えて下さ...
-
セッション関数を使わずにファ...
-
composerをインストールしたい...
-
SplFileObject を利用したとき...
-
PHPSpreadsheetによる書き出し...
-
phpの問い合わせフォームを作っ...
-
marginの値でマイナス値を設定...
-
submitで思うようにページが遷...
-
HTML PHP ラジオボタンのイベント
-
php でqiitaのサイトにあったフ...
-
PHPの勉強してます。 配列のと...
-
BASIC認証のフォームをデザイン...
-
アップロードファイルを表示す...
-
複数のパソコンの中の1つのパソ...
-
返信機能のツリー構造の深さを...
-
PHPについて。
-
PHPからCSVをアップロード後、m...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
foreachで上限回数指定方法また...
-
マッチング処理(1:N)
-
超難問 Scripting.Dictionary ...
-
Dictionary(連想配列?)の使い方
-
foreachとかの勝手な省略?
-
PHPの構文で間違えが分からない
-
PHPでこのコード自体に意味は無...
-
VB.NET で 二次元のハッシュは...
-
ftokが動かない?
-
Excel VBAでフィルター後の対象...
-
PHPで連想配列のプルダウンメニ...
-
PHP:ツリー構造をulとli要素に...
-
PHP、{}記号の意味
-
smartyでtplファイルでの2次元配列
-
配列の値によって条件分岐がし...
-
POSTで渡されるデータの数がわ...
-
pdfファイルの複数添付 引数の型
-
ulのネストをタブ区切りに変換...
-
リストボックス複数選択抽出方法
-
多次元配列の中で条件に合う要...
おすすめ情報