RedHat Linux ES2.1のperl v5.6.1にて初めてのプログラムを書いているものです。
Oracle9iに格納するDATE型のデータを大量に乱数にて作成しようとしているのですが、うまくいきません。
作成しようとしているのは2004年度か2005年度のある日付です(30日まで)。
例)
04-01-30
05-07-12
04-09-28
04-12-11
質問1.下のプログラムだと、年度が00,01,02,03,04,05の値をとり得てしまう。これを04か05に限定するにはどうすればよいか。
質問2.月・日が1桁の場合は0を頭につけたい。下のプログラムでは05-12-1となったり04-5-30となったりしてしまう。
#!/usr/bin/perl
$a = 1;
while($a < 100000){
$year_rand = int(rand(5));
$month_rand = int(rand(12))+1;
$day_rand = int(rand(30))+1;
print "0$year_rand-";
print "$month_rand-";
print "$day_rand,";
print "\n";
$a = $a+1;
}
宜しくお願い致します。
No.1
- 回答日時:
04と05に限定するなら、
$year_rand=int(rand(2))+3;
で強制的に1か2を発生させて、3を加えれば良いかと。
日付については、条件判断で、9以下なら
print "0$day_rand,";
10以上なら
print "$day_rand,";
で出来ませんか?
No.2
- 回答日時:
#1です。
間違えました。$year_rand=int(rand(1.9))+4;
こっちの方が良いかと。
0~1.9までの乱数を発生させて整数化するので0か1しか出来ません。それに4を加えてやる。
「日付については、条件判断で、」
月についても、条件判断で・・・
No.3
- 回答日時:
#1です。
もう一度・・・条件判断は、
if($month_rand>9){print "0";}
と、
if($day_rand>9){print "0";}
で良いかと・・・
(それぞれを、月と日付のprint文の前に挿入する。)
No.4
- 回答日時:
rand は rand(作りたい数) を与えます。
ここでは、04と05 の2つのなので、2が入ります。しかし、これでは0と1しか返って来ないので、ゲタを履かせます。それが+3です。
表示部分ですが、printf 関数を利用してしまった方が簡単でしょう。
多少、処理速度は落ちますが、あまり気にするほどの物でもありません。(中身は、C の printf です。)
\- は、- をマイナス記号と判定されない様に\を入れましたが、必要ないかも知れません(^_^;;)
$a = $a + 1;
は、
$a++;
の方が微妙にですが効率が良いです。
#!/usr/bin/perl
$a = 1;
while($a < 100000){
$year_rand = int(rand(2))+3;
$month_rand = int(rand(12))+1;
$day_rand = int(rand(30))+1;
printf("%02d\-%02d\-%02d\n", $year_rand, $month_rand, $day_rand);
$a++;
}
No.5ベストアンサー
- 回答日時:
質問1について
$r = int(rand(N)) では、0≦$r<N という範囲で乱数が発生しますので、
> これを04か05に限定する
には、その振れ幅である2を指定し(0か1が発生する)、最低値である4を足せばよいことになります。
つまり、
$year_rand = int(rand(2)) + 4;
質問2について
このような場合は printf が便利です。
printf では出力形式を指定することができ、2桁で頭を0埋めして出力、なども簡単にできます。
4行のprint文の代わりに、次のようにしてみてください。
printf "%02d-%02d-%02d,\n", $year_rand, $month_rand, $day_rand;
No.6
- 回答日時:
視点を変えてこんなのはどうでしょう?
#!/usr/bin/perl
require "timelocal.pl";
$time20040101=&timelocal(0,0,0,1,0,104);
$time20051231=&timelocal(59,59,23,31,11,105);
for(1..100)
{
$time=$time20040101+int(rand($time20051231-$time20040101));
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($time);
if($mday>30) continue;
printf("%02d-%02d-%02d\n",$year,$mon+1,$mday);
}
要約すると以下のとおりです。
timelocal.plというシステム関数を使います。
2004/01/01から2005/12/31までの日付を秒数に変換して、その差を乱数に与えます。
そうすると2年間のどこかの秒が得られます。
得られた乱数を2004/01/01の秒数に加えて得られた秒数をもう一度日付に変換します。
日が31日になったやつはもう一度やり直す。
どんな範囲の日付も簡単に作り出せますよ。
これがスマートなアルゴリズムというやつです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
1桁の日付に0を付ける
-
日付の差分の求め方(日、分)
-
Perlの日付の比較に関して
-
JSONで文字列が長い時
-
Application.ScreenUpdating = ...
-
VBAでPDFのコピーとリネームを...
-
メモリをアドレスを直接指定し...
-
「*:*」って何を意味するのでし...
-
実行中の変数の中身をイミディ...
-
UWSC SLCTBOXもしくはSELECTに...
-
C++ APIについて エラーコード...
-
[python] 文字列を変数名として...
-
Net::Telnetでタイムアウト時間...
-
UWSCのSELECT文の記述方法
-
メ-ルにno problem@の前にname...
-
VBAのNext forでエラーが出て困...
-
Perl:CGI.pm:入力ボックスのク...
-
エクセルマクロでフォルダのコ...
-
perl内のhtml文を、ループさせ...
-
VB6で、長い時間かかる処理...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
おすすめ情報