Perlでの無限ループについて
受付中
回答 1
投稿
- 評価
- クリップ 0
- VIEW 1,144
Perlで以下の文字列突合用のソースを書いたのですが、質問させてください。
一回目の<ファイルごとにループ>は無事に完了するのですが、二回目のループでは突合処理内の二回目のネストループで無限ループに入ってしまいます。
一回目と挙動は同じになるはずなのにこのような事象が出てしまうのは何故なのでしょうか。。
皆さまのお力をお貸し頂ければ幸いです。
一回目の<ファイルごとにループ>は無事に完了するのですが、二回目のループでは突合処理内の二回目のネストループで無限ループに入ってしまいます。
一回目と挙動は同じになるはずなのにこのような事象が出てしまうのは何故なのでしょうか。。
皆さまのお力をお貸し頂ければ幸いです。
#! /usr/bin/perl
### 格納リスト ###
@FILECHECK = ();
@NEWFILELIST = ();
@LASTFILELIST = ();
@TWONEWLIST = ();
@TWONLASTLIST = ();
@NEWCELLLIST = ();
@LASTCELLLIST = ();
@OUTPUT = ();
@OUTFIRSTPUT = ();
### 変数宣言 ###
$filecheck;
$newflag;
$lastflag;
$cnt;
$innewtmp;
$inlasttmp;
$newcnt;
$lastcnt;
$ReNewFileName;
$ReLastFileName;
$readnewline;
$readlastline;
# ファイル有無のチェック
@FILECHECK = glob("*");
# 配列要素の取得
$filecheck = @FILECHECK;
# 判定フラグ
$newflag = 0;
$lastflag = 0;
# エンコード
use Encode;
use utf8;
# ファイル分ループ
for(@FILECHECK){
if($FILECHECK[$cnt] eq "newapfile"){
$newflag = 1;
}elsif($FILECHECK[$cnt] eq "lastapfile"){
$lastflag = 1;
}elsif($cnt==$filecheck-1 && $newflag==0){
print "not there NewAPFile !!\n";
exit;
}elsif($cnt==$filecheck-1 && $lastflag==0){
print "not there LastAPFile\n";
exit;
}elsif($cnt==$filecheck-1 && $newflag==1 && $lastflag==1){
last;
}$cnt++;
}
print "Let's APmatching start !!\n";
### csvファイル一覧取得 ###\
@NEWFILELIST = glob("newapfile/*.csv");
@LASTFILELIST = glob("lastapfile/*.csv");
### ファイルごとにループ ###
for($newcnt=0; $newcnt<scalar(@NEWFILELIST); $newcnt++){
$ReNewFileName = 0;
$ReNewFileName = $NEWFILELIST[$newcnt];
$ReNewFileName =~ s/newapfile//g;
for($lastcnt=0; $lastcnt<scalar(@LASTFILELIST); $lastcnt++){
$ReLastFileName = 0;
$ReLastFileName = $LASTFILELIST[$lastcnt];
$ReLastFileName =~ s/lastapfile//g;
if($ReNewFileName eq $ReLastFileName){
print "matching $ReNewFileName\n";
print "matching $ReLastFileName\n";
print "Done..\n";
@OUTPUT = ();
@OUTFIRSTPUT = ();
push(@OUTFIRSTPUT, $ReNewFileName);
push(@OUTPUT, [@OUTFIRSTPUT]);
# 二次元配列用
@TWONEWLIST = ();
@TWONLASTLIST = ();
open INNEW, "<:encoding(shift-jis)", "$NEWFILELIST[$newcnt]" or die("could not open file.");
open INLAST, "<:encoding(shift-jis)","$LASTFILELIST[$lastcnt]" or die("could not open file.");
### ファイルを1行ずつ読み込んで二次元配列に格納 ###
$readnewline = 0;
while(my $readnewline = <INNEW>){
chomp $readnewline;
@NEWCELLLIST = ();
@NEWCELLLIST = split /\,/, encode("utf-8", $readnewline);
push(@TWONEWLIST, [@NEWCELLLIST]);
$i++;
}
close INNEW;
$readlastline = 0;
while(my $readlastline = <INLAST>){
chomp $readlastline;
@LASTCELLLIST = ();
@LASTCELLLIST = split /\,/, encode("utf-8", $readlastline);
push(@TWOLASTLIST, [@LASTCELLLIST]);
}
close INLAST;
$i=0;
$j=0;
### 突合処理 ###
while($i<scalar(@TWOLASTLIST)){
while($j<scalar(@TWONEWLIST)){
$k = 0;
$l = 0;
@OUTFIRSTPUT = ();
while($k<scalar(@{$TWOLASTLIST[$i]})){
while($l<scalar(@{$TWONEWLIST[$j]})){
# エラー2のケース(数値)
if($TWOLASTLIST[$i][$k] =~ /^[0-9]+$/){
if($TWOLASTLIST[$i][$k] == $TWONEWLIST[$j][$l]){
push(@OUTFIRSTPUT, "0,");
$k++;
$l++;
last;
}else{
push(@OUTFIRSTPUT, "1,");
$k++;
$l++;
last;
}
}
# エラー2のケース(マイナスの場合)
elsif($TWOLASTLIST[$i][$k] =~ /-/){
if($TWOLASTLIST[$i][$k] == $TWONEWLIST[$j][$l]){
push(@OUTFIRSTPUT, "0,");
$k++;
$l++;
last;
}else{
push(@OUTFIRSTPUT, "1,");
$k++;
$l++;
last;
}
}
# エラー2のケース(空白の場合)
elsif($TWOLASTLIST[$i][$k] =~ /\s/){
if($TWOLASTLIST[$i][$k] == $TWONEWLIST[$j][$l]){
push(@OUTFIRSTPUT, "ok null,");
$k++;
$l++;
last;
}else{
push(@OUTFIRSTPUT, "bad null,");
$k++;
$l++;
last;
}
}
# エラー1のケース(文字列)
else{
if($TWOLASTLIST[$i][$k] eq $TWONEWLIST[$j][$l]){
push(@OUTFIRSTPUT, "True,");
$k++;
$l++;
last;
}else{
push(@OUTFIRSTPUT, "FALSE,");
push(@OUTPUT, [@OUTFIRSTPUT]);
@OUTFIRSTPUT = ();
$j++;
$k = 0;
$l = 0;
last;
}
}
}
}
push(@OUTPUT, [@OUTFIRSTPUT]);
$j++;
$i++;
}
$i++;
}
open OUT, ">APmatching_$newcnt.csv";
for($m=0; $m<scalar(@OUTPUT); $m++){
print OUT encode("UTF-8", "@{$OUTPUT[$m]}\n");
}
close OUT;
}
}
}
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+1
おそらくですが、最後の方の
どんなデータが来るのか分からないので、再現させることはできませんでした。
もし違っていたら、発生条件や実行環境の情報も書いていただければと思います。
if-else
の、カウンター$k
をゼロにしているところに入ってしまうと、$k
のループを永久に抜けられないように見えます。
どんなデータが来るのか分からないので、再現させることはできませんでした。
もし違っていたら、発生条件や実行環境の情報も書いていただければと思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.23%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2014/11/17 10:48
2014/11/17 12:43
見落としの問題と思ったので、理由は省いてしまいました。
補足ありがとうございます。