みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

If分の記述???

1~31までの数字のうち、重複しない5つの数字をランダムに選び出し、ページ表示させるプログラムを作っているのですが、どういう訳か、最初のIf分の箇所が構文エラーでひっかかるんです。
一体、記述がどう間違っているんでしょうか?
PerlCGIはまだまだ初心者なので、どなたかHelpMe!(T_T)


#! c:/perl/bin/perl

#----------------------------------------数字生成
for ($i = 0; $i < 5; ++$i) {
#重複確認フラグリセット
$j = 0
while ($j = 1) {
#数字を選ぶ
$NUM = int(rand 31) + 1;
#重複チェック
#1個目確認処理なし
if ($i == 0) {
++$j;
}
#2個目確認処理
elsif ($i == 1) {
if ($Res[0] != $NUM) {
++$j;
}
}
#3個目確認処理
elsif ($i == 2) {
if ($Res[0] != $NUM and $Res[1] != $NUM) {
++$j;
}
}
#4個目確認処理
elsif ($i == 3) {
if ($Res[0] != $NUM and $Res[1] != $NUM and $Res[2] != $NUM) {
++$j;
}
}
#5個目確認処理
elsif ($i == 4) {
if ($Res[0] != $NUM and $Res[1] != $NUM and $Res[2] != $NUM and $Res[3] != $NUM) {
++$j;
}
}
}
#値代入
$Res[$i] = "$NUM";
}

#---------------------------------------ページ出力
print qq(Content-type: text/html; charset=Shift_JIS\n\n);
print qq(<HTML>\n);
print qq(<Head><Title>Test</Title></Head>\n);
print qq(<Body><Center><P>数字は...<BR><Big>\n);
for ($i = 0; $i < 5; ++ $i) {
print qq($Res[$i]<BR>\n);
}
print qq(</Big>です。</P><Center></Body></HTML>\n);

投稿日時 - 2003-02-04 03:58:59

QNo.463362

困ってます

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

すみません、訂正をしておりながらさらにミスがありました。

>あのぅ、教えて頂いた記述でちゃんと動いているようなのですが、
ランダム数の範囲が広いので一見まともに見えるだけです($Res[0]としか比較してないので)。
rand 6 にして試せば、駄目なのが分かります。

>インクリメントする$って、$jの事でしょうか?
$kです。ちょっと考えた限りでは、もう一個変数を使わないと全ての要素との比較が出来ないと思いました。真剣に考えれば、もっと旨い手があるかも。

>こんなに、シンプルなソースに出来るんですね!!
>ついついif文でガリガリ作ってしまって、こっそり
>「ややこしくなっちゃったな」って思ってました(^^ゞ
可読性が悪いといいながら、こちらも短いわりに結構ややこしいですけどね。
ただ、この手やり方はわりとよく使いますし、コメントでも入れとけば、何をやってるかは後からでもすぐ分かります。

で、責任とって修正版です。ミスやもっと簡単な方法があるかも知れないので、あとはご自身で、おっかけて、ノーテクと非難してください。(^^;

for ($i = 0; $i < 5; ++$i) {
$j = 0; #要素数
while ($j <= $i) { # ココ
$NUM = int(rand 31) + 1;
$flg = 1;
for ($k = 0; $k <= $j; $k++) { # ココ
print "$i:$j:$k\n"; # 表示して動きを確認
if ($Res[$k] == $NUM) {
$flg = 0;
last; # ココ 一致してたら残りの比較はヤメ
}
}
if ($flg) {
$Res[$i] = $NUM;
++$j;
}
}
}

投稿日時 - 2003-02-05 11:18:23

お礼

有難うございますー!!
追っていくうちに、頭の中がだんだんグルグルしてきたのですが、頑張って仕上げていきます!(^^)

投稿日時 - 2003-02-05 11:50:56

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.4

#3です。
御免なさい、どっかで $をインクリメントするルーチンを作ってください。

投稿日時 - 2003-02-04 11:36:29

補足

あのぅ、教えて頂いた記述でちゃんと動いているようなのですが、インクリメントする$って、$jの事でしょうか?

投稿日時 - 2003-02-05 02:15:30

お礼

こんなに、シンプルなソースに出来るんですね!!
ついついif文でガリガリ作ってしまって、こっそり「ややこしくなっちゃったな」って思ってました(^^ゞ
有難うございます!!(^^)

投稿日時 - 2003-02-05 02:15:06

ANo.3

#1,#2を合わせると動きます。

さらに余計なことですが、
5個だからまだいいけど、10個、20個必要になった場合大変ですよね。

そうなると可読性が良くないし、n個作れるように工夫した方が良いと思います。
方法はいろいろあるし、やっつけなのであまりよくありませえんが、↓こんな方法もあります。

for ($i = 0; $i < 5; ++$i) {
$j = 0;
while ($j < 5) {
$NUM = int(rand 31) + 1;
$flg = 1;
$k = 0;
if ($Res[$k] == $NUM) {
$flg = 0;
}
if ($flg) {
$Res[$i] = $NUM;
++$j;
}
}
}

投稿日時 - 2003-02-04 11:32:14

余計なことですが
> while ($j = 1)
無限ループになってしまいます。。。

投稿日時 - 2003-02-04 09:14:26

ANo.1

まだ全部は見てないですけど、

#重複確認フラグリセット
$j = 0

↑セミコロン忘れてますが、
 これはここに入力する時に欠落?(^^;

投稿日時 - 2003-02-04 08:37:45

お礼

ついつい、忘れていたようです。
有難うございます(^^)

投稿日時 - 2003-02-05 01:57:58

あなたにオススメの質問