
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.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日になったやつはもう一度やり直す。
どんな範囲の日付も簡単に作り出せますよ。
これがスマートなアルゴリズムというやつです。
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.3
- 回答日時:
#1です。
もう一度・・・条件判断は、
if($month_rand>9){print "0";}
と、
if($day_rand>9){print "0";}
で良いかと・・・
(それぞれを、月と日付のprint文の前に挿入する。)
No.2
- 回答日時:
#1です。
間違えました。$year_rand=int(rand(1.9))+4;
こっちの方が良いかと。
0~1.9までの乱数を発生させて整数化するので0か1しか出来ません。それに4を加えてやる。
「日付については、条件判断で、」
月についても、条件判断で・・・
No.1
- 回答日時:
04と05に限定するなら、
$year_rand=int(rand(2))+3;
で強制的に1か2を発生させて、3を加えれば良いかと。
日付については、条件判断で、9以下なら
print "0$day_rand,";
10以上なら
print "$day_rand,";
で出来ませんか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
日付の差分の求め方(日、分)
-
前日の日付取得するには?
-
ローカルだと改行されるのに、...
-
perlでcheckboxがうまく整理で...
-
Perlの乱数について
-
年月日の数値化?
-
月見る月はこの月の月
-
パールスクリプトのif else文に...
-
perl セレクトメニューを ↓の...
-
Perlの日付取得で月の表示がお...
-
サマータイムの判定について
-
CSV読み込み時に条件に合う行(...
-
Cookieの有効期限について
-
T-SQL(SQL Server2000) 月数の...
-
Perl スクレイピング処理につ...
-
Application.ScreenUpdating = ...
-
JSONで文字列が長い時
-
メモリをアドレスを直接指定し...
-
実行時エラー 3020の対策
-
formで特定のinputを送信しない...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
おすすめ情報