トップページ⇒php
1001コメント364KB

Perl コーディング初心者質問コーナー Part36

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん04/07/14 13:23ID:???
いらっしゃーい、Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。

1: 自分はこう言う事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。

最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。

過去ログやお勧めサイトは >>2-10
0116nobodyさん04/07/23 01:34ID:???
>>115
GETじゃなくてHEAD
HTTPの仕組みくらい調べましょう
011711104/07/23 01:39ID:TCCtsz0d
>>116
HEADだと何も帰って来ないんです。
からっぽです。
0118nobodyさん04/07/23 01:41ID:???
>>117
http://www.studyinghttp.net/
http://member.nifty.ne.jp/hippo2000/perltips/LWP.html
011911104/07/23 01:43ID:TCCtsz0d
>>118
両方とも紫色です・・・。
012011104/07/23 02:04ID:TCCtsz0d
なんと出来ました。

require LWP::UserAgent;

$ua = LWP::UserAgent->new;

$request = HTTP::Request->new('HEAD', 'http://akky.cjb.net');

$response = $ua->request($request);
($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime($response->headers->last_modified);
$year += 1900;
++$mon;
print "更新時:$year年$mon月$mday日 $hour時$min分$sec秒\n";
012111104/07/23 02:06ID:???
訂正:なんと"か"出来ました。
0122nobodyさん04/07/23 11:00ID:???
質問です。自分でGIF画像のカウンタを作っています。

ソース:
ttp://tool-ya.ddo.jp/2ch/trash-box/file/20040723105619092.zip

gifcatで連結して出力する場合、ブラウザで確認すると、桁が左側から順に表示されてしまいます。
連結されて一つの画像になっているにもかかわらず、桁ごとに表示されるという現象が起こっています。
一桁ずつ順に表示するのではなく、例えば5ケタなら5ケタ分を一気に表示させたいのですが、
どのように記述すればいいのでしょうか。
0123nobodyさん04/07/23 11:45ID:???
>>122
GIFアニメだから
0124nobodyさん04/07/23 11:45ID:???
>>122
猫は GIF アニメーションを使って擬似的に連結しているからねぇ。
0125nobodyさん04/07/23 14:01ID:???
gifcatやstrcatの cat をマジでネコだと思ってるヤツって、どれくらいいるんだろなw
0126nobodyさん04/07/23 14:06ID:???
>>125
釣りの勉強が足りてませんよ
0127nobodyさん04/07/23 14:18ID:???
catコマンドはもともと猫であってるよ。
でもそれじゃあ格好がつかない というわけで
連結(conCATenate)だと由来を後付した。
0128nobodyさん04/07/23 14:35ID:???
125立つ瀬ねえなw
0129nobodyさん04/07/23 14:48ID:???
かわいそうな>>125
0130nobodyさん04/07/23 15:22ID:???
>>125
(・∀・)ニラニラ
0131nobodyさん04/07/23 15:57ID:???
             . ィ   >>125
.._ .......、._    _ /:/l!  そんなエサでぬこさまが(ry
 :~""''.>゙' "~ ,、、''‐'、|         _      
゙、'、::::::ノ:::::::_,.-=.  _〜:、         /_.}'':,
 ``、/:::::::::__....,._ `゙'Y' _.ェ-、....._ /_゙''i゙ノ、ノ
 ,.--l‐''"~..-_'.x-='"゙ー 、`'-、 ,:'  ノ゙ノブ     
"   .!-'",/  `'-‐'') /\ `/ でノ-〈
 .-''~ >'゙::    ‐'"゙./  ヽ.,'   ~ /
   //:::::       ',    /    ,:'゙
0132nobodyさん04/07/23 16:31ID:???
ワロタ
>>125再降臨キボンヌ
0133nobodyさん04/07/23 17:17ID:???
質問いいでしょうか。BBSにワード検索機能を付けたのですが、

foreach $temp (@line) {                      # @lineはログ
 $temp =~ s/\s*$//;
 @data = split (/\t/, $temp);                   # タブ区切りなのでタブで分割
 if (index ($data[0] . $data[1] . $data[2], $words) > -1) { # 名前,メール,本文 $wordはフォームから受け取った検索ワード
  push (@new, $temp);
 }
}

このようにして、@newの中身をforeachで書き出せば、指定語句を含むものだけは書き出せました。
これを、検索ワードをスペース区切りで複数指定可能にしてAND検索をできるようにしたいと思っています。

$word =~ s/\x81\x40/\t/g;                    # スペースで区切って入力されたフォームの検索ワードをタブ区切りにする
@words = split (/\t/, $word);                   # 検索ワードをタブで区切って配列に入れる

この2行を追加して検索ワードを複数取得したのはいいのですが、indexの第二引数の部分で@wordsの中身を全て含む場合の記述方法が思い浮かびません。
どのような記述方法があるのでしょうか。
013413304/07/23 17:43ID:???
$word =~ s/\x81\x40/\t/g;
@words = split (/\t/, $word);
foreach $temp (@line) {
 $temp =~ s/\s*$//;
 @data = split (/\t/, $temp);
 foreach (0 .. $#words) {
  if (index ($data[1] . $data[2] . $data[6], $words[$_]) > -1) {
   push (@new, $temp);
  }
 }
}

このように記述してしまうと、検索ワードを複数指定した場合、
「検索ワードを含む記事の数 * 検索ワード数」分の記事が出てしまうのです。
 Ex1.
 「オレオレ!ばぁちゃん、車ぶつけて50万必要なんだ」という記事がある場合、
 検索ワードを「オレオレ ばぁちゃん 車ぶつけて 50万必要」などとすると、同じ記事が4つ@newの中に入ってしまいます。
 Ex2.
 「オレオレ!ばぁちゃん、車ぶつけて50万必要なんだ」という記事と、
 「オレオレ!ばぁちゃん、車ぶつけて50万必要なんです」という記事がある場合、
 検索ワードを「オレオレ ばぁちゃん 車ぶつけて 50万必要」などとすると、
 「〜必要なんだ」という記事が4つ、「〜必要なんです」という記事が4つの計8つが@newの中に入ってしまいます。
0135nobodyさん04/07/23 17:50ID:???
じゃあ、どうしたらいいと思う?
013613304/07/23 18:00ID:???
>>134の
>  if (index ($data[1] . $data[2] . $data[6], $words[$_]) > -1) {
この部分は
  if (index ($data[0] . $data[1] . $data[2], $words[$_]) > -1) {
の間違いです。失礼しました。
0137nobodyさん04/07/23 18:18ID:???
>>133-134
http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlsyn.html#Loop_Control
0138nobodyさん04/07/23 18:20ID:???
>>133
そこまで書けるんならそんな難しい事じゃないと思うぞ。
foreachの中でマッチするたんびにpushしてるからそうなるんであって、
flag設定してflagたった時だけpushするとか、
grepで一個でもtrue返したらpushするとか。
方法はいろいろあると思うけど、もうちょっと自分で考えてみれば?
0139nobodyさん04/07/23 18:43ID:???
>>138
無駄フラグ作ったり、grepで全検査するよか
 LINE: foreach $temp (@line) {
   ・・・
   foreach (0 .. $#words) {
     next LINE if index($data[0] . $data[1] . $data[2], $words[$_]) == -1;
   }
   push (@new, $temp);
 }
のがいいのでは?
>>137はそういうことではないかと。
0140nobodyさん04/07/23 18:52ID:???
まあ、だからそういうふうに、
いろいろ方法はある訳で、
ちょっとは自分で考えたら?
と言いたいわけですわ
0141nobodyさん04/07/23 19:22ID:???
>>140
漏れは元質問者じゃねーが、壷に嵌ったときはさらさらコードを書けるが、ドツボに嵌った時は何をやっても書けない。。。
そんな時つい2ちゃんに書きたくなるんだよ。
0142nobodyさん04/07/23 19:28ID:???
しかし、一歩も踏み出さずに投げられても、
それこそ幾通りも方法はあるし、それじゃ
丸投げと同じじゃんよ。
少しは自分で考えてやってみろって、
それでうまく行かないってんならアドバイスのしようもあるけど、
0143nobodyさん04/07/23 19:46ID:???
>>125はまだ来ないの?
0144nobodyさん04/07/23 19:52ID:???
むしろ>>126に来てほしい
014512604/07/23 20:14ID:???
呼んだ?
0146nobodyさん04/07/24 03:47ID:???
呼んでないよ
0147nobodyさん04/07/24 07:58ID:???
>>146
本人必死だな(pgr
0148nobodyさん04/07/24 08:46ID:???
あははは!
おーい、そろそろ次の質問をどうぞー。
みんな暇してるゾ。
0149nobodyさん04/07/24 10:01ID:???
printf("%s",substr(<<EOT,0,-1).substr(<<EOU,0,-1).substr(<<EOV,0,-1));
\x8e\x9f\x82\xcc
EOT
\x8e\xbf\x96\xe2
EOU
\x82\xc7\x82\xa4\x82\xbc
EOV
015013304/07/24 17:26ID:???
色々なレスありがとうございました。
もう少し色々実験してみます。
0151nobodyさん04/07/25 04:48ID:???
@fooに\nで区切られた文字列があって、
5000文字に一番近い\nごとに区切りたい(4951文字目のあとに\nが来れば、4951文字目まで、とそれから5000文字に一番近い\nまで、という感じです)のですが、
substrを使ったら\nの個数がでてきたり、と全くわけがわからなくなってしまいました。
ご教授願えませんでしょうか。
0152nobodyさん04/07/25 06:27ID:RBsrNYZO
>>151
わけがわからないのはお前の質問だ。落ち着いてわかるように書け。

とりあえず突っ込みどころとしては

配列@fooに文字列が入ってるってどういうことよ?

5000文字に一番近い\nっていうが、4999文字目と5001文字目に\nが
あったらどっちが一番近いのか?

一番近いの\nごとというが、一番近いのは1つじゃないのか?

\nがなかったらどうするよ?
0153nobodyさん04/07/25 06:47ID:???
|←   5000文字   →|
@@@@@@@\n
@@@\n@@@@\n
@@@@@@\n
@@@@@@@@@\n

こんな感じに幅を合わせたいんじゃない?
5000文字目から後ろに\nを探して最初に見つかったところで──って感じかなあ。
正規表現は{,5000}みたいに大きな数字は扱えなかったような気がするので、
ループが入るとは思う。
0154nobodyさん04/07/25 07:00ID:???
>152-153
>153さんのいうような感じで、5000以下のパケットのようなものを作りたいんです。
具体的に言うと、
ページを携帯電話対応に書き換えるスクリプトを作ってるんですが、
ヘッダをとって、body部分を6KB以下に分けたいんです。
ただ、改行で切らないと、タグの途中で切れたりしちゃうので、それを避けるために一番近い(以前に、です)\nを探す、というのも必要だったんです。
0155nobodyさん04/07/25 08:18ID:???
>>151
じゃあヒント。

ループでひとつ毎にサイズ計測。
欲しいサイズまで確認できたらループ脱出。
0156nobodyさん04/07/25 09:21ID:???
>>155
foreachですかね。
0157nobodyさん04/07/25 09:25ID:???
(´-`).。oO(一定サイズで切るとは変わったアプローチだな・・・)
0158nobodyさん04/07/25 10:03ID:???
タグが<a
href="hoge">
とか二行に分かれてたらどうすんだよ。
0159nobodyさん04/07/25 10:12ID:???
>>158
あ、大丈夫です。自分のサイト用ですので。
0160nobodyさん04/07/25 11:44ID:???
>>159
じゃあ、携帯用改ページタグでも埋め込んどけば?
0161nobodyさん04/07/25 16:36ID:???
前の話題も終わってないのに申し訳ないですが、質問させてください。

二つのCGIがあり、片方はフォームからPOSTで。
もう片方は<a href= でリンクで飛ばしています。
これらを別のCGIで吐き出されるページで使いたいのですが、
片方ずつならちゃんと動作するのに、両方を同時に設置するとどちらもエラーになります。
GETとPOSTは共存できないのですか?
0162nobodyさん04/07/25 17:12ID:???
ンなアホな
0163nobodyさん04/07/25 17:27ID:???
>>161
タイトルと >>1 を読んでくださいねー
0164nobodyさん04/07/25 17:36ID:???
>>161
んだ。イメージが全然浮かばない。
クライアントからの1リクエストにGETとPOSTを同時に含めることはできない。
URLにGETもどきのパラメータを仕込んでPOSTすることは可能。
・・・って、くらいしか答えられん。
0165nobodyさん04/07/25 20:19ID:???
>>151

substr($x, 0, 1+rindex($x, "\n", 4999))

よくわからんが結局こういうことがやりたいのだろうか?
5000文字以内に改行がないときは空文字列になるけど、
いやなら適当に直してね。
0166nobodyさん04/07/25 22:29ID:???
Perlで画像貼り付け掲示板を製作中なんですが、
引っ張ってくる画像が閲覧可能であるか、不可であるのかは判別可能でしょうか?
思考錯誤してますがどうにも苦戦中です。
何卒ご指導お願いします
0167nobodyさん04/07/25 22:33ID:8FggQcGj
チャット参加者一覧を作りたいのですが
http://〜/member.dat のようなファイルをHTMLで読見込むにはどうしたらよいでしょう?
勿論Perlでも構いません
教えてください
0168 ◆jHejx.Ji8k 04/07/25 23:01ID:???
ActivePerlとApacheをインストールしてApacheを起動させました。
それで、CGIを実行出来るかアドレスを打ったのですが、

ファイルのダウンロード

ファイルによっては、コンピューターに問題を起こす可能性があります。
以下のファイル情報に関して疑わしい点がある場合や、発信元が完全に信用で
きない場合は、このファイルを開いたり保存したりしないでください。

ファイルを開くか、ファイルをコンピューターに保存するか選択してください。

と、でてしまい開くを押しても何も起こりません。
どうすればCGIを実行出来るんでしょうか?
0169nobodyさん04/07/25 23:16ID:???
>>166-168
3 匹合わせて、、あん・ぽん・たん!
スレッドタイトルと、 >>1 を読んでくださいね。
0170 ◆jHejx.Ji8k 04/07/25 23:52ID:???
>>169
すません、わかりました。
ありがとうございました。
0171nobodyさん04/07/26 00:33ID:???
>165
それです。完璧です。有難う御座いました。
0172nobodyさん04/07/26 01:11ID:???
openでエクセルのファイルを開いて@dataに入れたんですが、
呼び出すと、文字化けしてます。content-typeが問題な気もするんですが、どうしたらいいんでしょうか。
017317204/07/26 01:20ID:???
txtでタブ区切りで作って、拡張子を変えたら使えました。謎です。
0174nobodyさん04/07/26 05:28ID:???
アホか・・・
017513304/07/26 14:29ID:???
>>133です。
突っ込もうとしているログのデータが配列内に無かった場合のみ、という判定方法で正常に動作しました。
ありがとうございました。

$word =~ s/\x81\x40/\t/g;
@words = split (/\t/, $word);
foreach $temp (@line) {
 $temp =~ s/\s*$//;
 @data = split (/\t/, $temp);
 if (index ($data[1] . $data[2] . $data[6], $words[$_]) > -1) {
  if (!grep $temp eq $_, @new) {
   push (@new, $temp);
  }
 }
}

017613304/07/26 14:35ID:???
正常に動作してなかった・・・。
ちとタンマ。
0177nobodyさん04/07/26 15:15ID:???
>>175
<q cite="http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlfaq4.html#How_can_I_tell_whether_an_list_o">

$is_there = grep $_ eq $whatever, @array;

だとか

$is_there = grep /$whatever/, @array;

のようなやり方はしないでください。

これらのやり方は遅く(最初に対象が見つかったとしてもすべての要素を
検査していしまいます)、非効率(同じ理由です)で、バグの可能性を含んで
います ($whatheverに正規表現キャラクターがあったりしたら?)。
</q>
017813304/07/26 15:23ID:???
>>177
grepはNGですか、foreachに書き換えることにします。
ちなみに>>175のコードって、これはOR検索になってますね orz
017913304/07/26 18:16ID:???
ようやく動きました。アドバイスありがとうございました。

$word =~ s/ | /\t/g;         #  スペースで区切って入力されたフォームの検索ワードをタブ区切りにする
@words = split (/\t/, $word);    #  検索ワードをタブで区切って配列に入れる
if ($search eq "and") {        #  検索方法がAND形式である場合
  foreach $temp (@line) {      #  配列の数だけ繰り返す
    $temp =~ s/\s*$//;      #  行末の改行コードや空白を取り去る
    @data = split (/\t/, $temp); #  一行取り込んだ部分を分割して配列に格納する
    @check = ();           #  チェック用配列を初期化
    foreach (0 .. $#words) {    #  検索ワードの数だけ繰り返す
      if (index ($data[1] . $data[2] . $data[6], $words[$_]) > -1) { #  配列から取得した名前、メールアドレス、本文を結合したテキスト内を検索して、検索ワードが存在した場合
        push (@check, 1);   #  チェック用の配列に1を入れる
      } else { #  配列から取得した名前、メールアドレス、本文を結合したテキスト内を検索して、検索ワードが存在しない場合
        push (@check, 0);   #  チェック用の配列に0を入れる
      }
    }
    $output_flg = 1;         #  データ出力用フラグを用意する
    foreach (@check) {       #  配列の数だけ繰り返す
      if (!$_) {            #  チェック用の配列に0がある場合
        $output_flg = 0;     #  データ出力用フラグを0にする
        last;            #  ループを抜ける
      }
    }
    if ($output_flg) {        #  データ出力用フラグが立っている場合
      push (@new, $temp);   #  検索ワードが存在するログの行を新しい配列に格納する
    }
  }
018013304/07/26 18:17ID:???
} else {                  #  検索方法がOR形式である場合
  foreach $temp (@line) {      #  配列の数だけ繰り返す
    $temp =~ s/\s*$//;      #  行末の改行コードや空白を取り去る
    @data = split (/\t/, $temp); #  一行取り込んだ部分を分割して配列に格納する
    foreach (0 .. $#words) {    #  検索ワードの数だけ繰り返す
      if (index ($data[1] . $data[2] . $data[6], $words[$_]) > -1) { #  配列から取得した名前、メールアドレス、本文を結合したテキスト内を検索して、検索ワードが存在した場合
        $exist_flg = 0;      #  データ存在フラグを用意する
        foreach $_ (@new) {  #  配列の数だけ繰り返す
          if ($_ eq $temp) {  #  ログから取り込んだ一行が新しい配列内にあるデータと一致する場合
            $exist_flg = 1;  #  データ存在フラグを立てる
            last;        #  ループを抜ける
          }
        }
        if (!$exist_flg) {     #  データ存在フラグが立っていない場合
          push (@new, $temp); #  検索ワードが存在するログの行を新しい配列に格納する
        }
      }
    }
  }
}

grepの部分も>>177が提案してくれた方法で書いてみました。
0181nobodyさん04/07/26 18:21ID:QB5gv79+
携帯用のサイトを作っているのですが、質問させてください。ある変数の中に
「DoCoMo 2.0 N900i(c100;TB;W24H12;ser***;icc***) 」 (***はランダムな英数字)
という文字列が入ってるとして、「(」以降を切り捨てて
「DoCoMo 2.0 N900i」だけにするにはどうすればよいのでしょうか?
substrで桁数を指定するしかない?
0182nobodyさん04/07/26 18:26ID:???
>>181
そこで正規表現ですよ。
というか、いろんな方法があるから好きなのを選べばいいと思う。
0183nobodyさん04/07/26 18:27ID:???
s/\(.+\)//
0184nobodyさん04/07/26 19:24ID:84cm3KM0
>>133
どうでもいいけど無駄多いな

@words = /([^ | ]+)/g;
foreach (@line) {
  s/\s+$//;
  @data = split(/\t/);

  $hit = 0;
  foreach $sword (@words) {
    $hit++ if index("$data[1]$data[2]$data[6]", $sword) > -1;
  }

  next if !$hit;

  push(@new,$_) if $search ne 'and' or $hit == $#words + 1;

}

じゃだめか?
0185nobodyさん04/07/26 19:26ID:???
@words = ($word =~ /([^ | ]+)/g);

こうか
018618104/07/26 20:14ID:QB5gv79+
>>182
携帯からでしか確認できないのと今手元に実機がないので
また失礼します。何度もすいません。
$data = s/.+(.+)//;
でいけますかね?これで「(」と「)」にはさまれた部分を削除できる・・・かな?
0187nobodyさん04/07/26 20:28ID:???
>>186
$data =~ s/(.+)\(.+\)/$1/;
018818104/07/26 20:47ID:QB5gv79+
>>187
レスありがとうです。
私はアホなので意味がさっぱりわからないんですが
これそのままコピペしてもいいのかな・・・。
ちょっと拝借して明日動作確認してみますね。
というか>>183さんも今見たらアドバイスくれてたっぽいですね。
こっちも私には難解だけどありがとうです。
0189nobodyさん04/07/26 23:50ID:???
>>133
どうでもいいが、and検索時にログに検索対象の文字列の有無を判定する時に、
配列に0やら1やらを突っ込んで後からチェックするってやり方が俺と同じだ。

わからないときはフリーのソースでも拾って参考にしなさい。
0190nobodyさん04/07/27 00:02ID:???
どうでもいいが、本7か?
019113304/07/27 00:11ID:???
>>133です。
>>184-185氏、そのような書き方もあるのですね。
自分はまだ色々と省略されると見直す際にワケわからなくなるので、
まどろっこしくても極力ああいったソースの書き方をするようにしています。
それらのソースも参考にして、もう少し改善してみようと思います。
とりあえずは動くので失礼します。
ありがとうございました。
0192nobodyさん04/07/27 00:23ID:???
>>191
184-185 は無視しておきましょう。
あと、検索部。
if (index ($data[1] . $data[2] . $data[6], $words[$_]) > -1)
検索語が跨ぐ場合も考えられますのでご注意の程を。
ex.
$data[1] = '2004/07/27';
$data[2] = 'sage';
$data[6] = 'test test test';
@word = qw|27sa agete|;
0193nobodyさん04/07/27 00:26ID:???
>>181
($foo,$bar) = split(/(/,$aruhensuu);
で、$fooじゃダメか?
0194nobodyさん04/07/27 02:53ID:tzLxOAtQ
入出力ファイルフォーマットが変更になった場合、
関係部分のコーディングを全て修正するのは大変なのですが、
c言語のように、ファイルフォーマットのマクロ定義みたいなことは、perlでは
できないのでしょうか?
0195nobodyさん04/07/27 05:16ID:???
>>194
そういうのは OO 的アプローチで解決する方がスマートだが、
こういうものもある。
http://perldoc.com/perl5.8.4/pod/perlfilter.html
0196nobodyさん04/07/27 10:11ID:lcTiWytf
フォームCGIを、unicode 対応しようとしているのですが、うまくいきません。
Perl のバージョンは、Ver 5.8.0 なので、

フリーのCGIを利用して

�@ CGIにに、 use utf-8; 行を追加
�A CGI中の、 jcode.pl を利用している部分を削除
�B 送信用HTMLをutf-8 に変更

し、送信テストを試みるのですが、受信したメールが文字化けしてしまいます。

レス頂ければ幸いです。
0197nobodyさん04/07/27 10:27ID:???
>>196
レスしてやろう。

>>1-7
0198nobodyさん04/07/27 10:32ID:???
>>196
正直な話、スクリプト改造丸投げスレの方が君に合っていると思う
019918104/07/27 11:40ID:5fKcxtBP
遅くなりましたけど、>>187の方法でうまくいきました。
ありがとうでした。あと>>193さんもありがとう。まだ試してないけど
今後のために保存しておきます。皆様感謝感謝〜 m(_ _)m
0200nobodyさん04/07/27 12:14ID:q+Q9Gs/i
次のようなリストに行を追加するのに、通し番号を付けたいんだが
1111,データ1
1112,データ2
1115,データ5

最大値をとってそれに1を足そうとしたんだけれど
$noに1だけ入ってしまいます。どうも最大値が文字列
扱いされているようです。
どんな感じになおしたらいいだろうか。

while(<IN>){
chomp;
$record{(split(/,/,$_))[0]} = $_;
}
$no = ((((sort keys %record))[-1]));
$no++;
close (IN);
0201nobodyさん04/07/27 12:40ID:???
オレの手元でそのプログラムにそのデータを食わせると
1116になるので、その意味では直す必要はないよ。
ここに書いてない部分がおかしいか入力ファイルがおかしいか
というあたりだろう。もう一度良く見ろ。

特にwhileループ抜けたあとで%recordがどうなってるか、sortのあと
$no++する前の$noの値はどうなってるか、といったあたりを確認
することをオススメする。
0202nobodyさん04/07/27 12:41ID:???
ついでにもう1つ。番号の部分が4ケタ固定ならそれでもいいが、
そうでないならsortは文字列比較がデフォルトなので、<=>を
使った比較を明示しないとおかしくなるよ。
0203nobodyさん04/07/27 12:48ID:5NNnTCFI
从リ ゚д゚ノリ ハァ?
最大値取るだけで、意味不明なことやりすぎ。
↓で十分だろ

while(<IN>){
  if (m/^(\d+),/) {
    $max = $1 if $max < $1;
  }
close (IN);

0204nobodyさん04/07/27 13:20ID:YbDKdELb
再利用するんだろうよ
0205黒死犬 ◆EgxBlf8nvc 04/07/27 14:08ID:???
>>200
外の括弧が余計なのでは?
リストとしてスカラーに代入すると、そのリストの長さが入っちゃいます
0206nobodyさん04/07/27 14:10ID:???
@hoge1=( "1", "1", "1", "3", "4", "5", "5" );
@hoge2=( "1", "2", "4", "5" );

foreach(0..@hoge1 -1){
 if($hoge1[$_] ne $hoge1[1+$_] ){
  push(@hoge3,$hoge1[$_]);
 }
}

foreach(0..@hoge2 -1){
 foreach$wk(0..@hoge3 -1){
  if($hoge3[$wk] eq $_){
   push(@hoge4,$_);
  }
 }
}

結果
@hoge4の中身
"1"
"4"
"5"

質問させて頂きます。
@hoge1、@hoge2の要素を比較して同一だった要素を
@hoge4のように1つだけ取り出す為に上記のようにしてみましたが
効率が悪いような気がします。
もっとスマートに出来る方法はないでしょうか?

020720604/07/27 14:21ID:???
@hoge3はあとで使いますので別ループにしてあります。
0208nobodyさん04/07/27 14:27ID:???
hash使え。

foreach (@hoge1) { $h{$_} = 1; }
@hoge4 = grep {$h{$_}} @hoge2;

一例としてはこんなとこか?
0209黒死犬 ◆EgxBlf8nvc 04/07/27 14:30ID:???
@hoge2、@hoge3 は常にソートされていて、重複した値を含まないのなら

my $m = 0;
my $n = 0;

while($m <= $#hoge2 and $n <= $#hoge3) {
 if($hoge2[$m] < $hoge3[$n]) {
  push(@hoge4, $hoge2[$m++]);
 } else {
  $hoge2[$m] == $hoge3[$n] and $m++;
  push(@hoge4, $hoge3[$n++]);
 }
}

テストしてないので動作に保証出来ません(単にマージしただけだけど)
Perlだと、組み込みのハッシュ使った方が早いかも
0210nobodyさん04/07/27 16:02ID:???
>>206
後はこんなんとか、

@hoge1=( "1", "1", "1", "3", "4", "5", "5" );
@hoge2=( "1", "2", "4", "5" );
print sort keys %{{map{($_ => 1)}@hoge1,@hoge2}};
0211nobodyさん04/07/27 16:33ID:???
>>210
それ動かしてみたけど12345になるぞ。
期待している結果は1,4,5だったはず。
021220604/07/27 17:35ID:???
>>208
grepを使って何とか出来ないかと思っていたのですが
hashを利用しての真偽判定でしたか。
大変参考になりました。どうもありがとうございました。
0213nobodyさん04/07/27 17:41ID:???
>>207
@hoge3みたいに重複した要素を取り除いた結果が欲しかったら

@hoge1 = grep(!$h{$_}++, @hoge1);

0214nobodyさん04/07/27 17:47ID:???
↑とperlメモのコピペを貼るやつ
0215nobodyさん04/07/27 17:53ID:???
perl でリモートデバッグやっている人います?
いるとしたらどんなツールを使っていますか
■ このスレッドは過去ログ倉庫に格納されています