初めまして、説明がうまく伝わらないかもしれませんがよろしくお願いいたします。
同じ値がN回続いた場合、その値をすべて出力するPerlのプログラムを作成中なのですが
とても長くなってしまい、スッキリとしたプログラムにしたいのです。
どうかお知恵を貸していただけないでしょうか。
現在、&&を使用してこのようになっています。
例:Aの値が5回連続して同じ値だった場合
for($i=1; $i<=1000; $i++){
if(@A[$i]==@A[$i+1] && @A[$i+1]==@A[$i+2] && @A[$i+2]==@A[$i+3] && @A[$i+3]==@A[$i+4]){
for($j=0; $j<=9; $j++){
printf "@A[$i+$j], @B[$i+$j], @C[$i+$j]";
}
}
}
データはすべて数値で、スペース区切りのテキストデータです。
# ヘッダー
0.00 2.0 11.5
0.01 6.3 17.2
0.01 2.1 14.2
0.01 1.2 14.3
0.01 2.1 14.3
0.01 3.7 14.3
0.01 3.7 14.3
0.01 4.1 14.3
0.06 4.1 14.3
0.01 4.1 14.9
0.01 4.1 14.9
0.03 4.1 14.8
・・・
連続した値が50回、100回だった場合になるとif文の条件式が長くなってしまい
その都度変更がとても大変になってしまい困っています。
どうか、よろしくお願いいたします。
No.4ベストアンサー
- 回答日時:
Perlはちょっとうろ覚えですが、単に取り出すだけなら文字列のまま取得してもいいかも。
------------------
$N= 5;
$n=$N-1;
@arr;
while ( $str =~ m/(([\d\.]+) [\d\.]+ [\d\.]+\n(?:\2 [\d\.]+ [\d\.]+\n){$n,})/og ){
push(@arr,$&);
}
#確認
print "<pre>";
foreach $var (@arr) {
print "$var<hr>";
}
print "</pre>";
------------------
~以上ではなく、厳密にN回なら カンマなしで{$n}
No.7
- 回答日時:
再帰呼び出しで比較、カウンタ変数で連続回数を判定すればいいような気がします。
#!/usr/bin/perl
use strict;
use warnings;
use feature qw/say switch/;
use utf8;
use open IO => qw/:utf8 :std/;
my @list = <DATA>; # 比較する数値が入ったリスト
my @kaburi = (); # 繰り返しの数値が入るリスト
my $count = 0; # カウンタ変数
sub yobidasi {
my $num = shift @_;
$count++;
yobidasi(shift @list) if defined $list[0] && $num eq $list[0];
push @kaburi, $num if $count > 1; # ここの数値で連続回数を指定
$count = 0;
}
while (my $num = shift @list) {
yobidasi($num);
}
say @kaburi;
__DATA__
0.00 2.0 11.5
0.01 6.3 17.2
0.01 2.1 14.2
0.01 1.2 14.3
0.01 2.1 14.3
0.01 3.7 14.3
0.01 3.7 14.3
0.01 4.1 14.3
0.06 4.1 14.3
0.01 4.1 14.9
0.01 4.1 14.9
0.01 4.1 14.9
0.01 4.1 14.9
0.01 4.1 14.9
0.01 4.1 14.9
0.01 4.1 14.9
0.01 4.1 14.9
0.01 4.1 14.9
0.01 4.1 14.9
0.03 4.1 14.8
で、出力はこんな感じなると思います。
0.01 3.7 14.3
0.01 4.1 14.9
比較の条件がよくわからなかったので、行単位での文字列比較で再帰呼び出しを行っています。ここはsplit使うなりして、お好きなように設定してみてください。
お礼が遅くなり申し訳ありませんでした。
内容を理解するまで少し時間をいただけないでしょうか。
丁寧にご回答をしていただき、ありがとうございました。
何とか頑張ってみます。
No.5
- 回答日時:
Ano3 書き落としすみません。
$strは文字列のままのデータ全部です。$str = "
# ヘッダー
0.00 2.0 11.5
0.01 6.3 17.2
0.01 2.1 14.2
0.01 1.2 14.3
0.01 2.1 14.3
0.01 3.7 14.3
0.01 3.7 14.3
0.01 4.1 14.3
0.06 4.1 14.3
0.01 4.1 14.9
0.01 4.1 14.9
0.03 4.1 14.8
";
No.3
- 回答日時:
こんな感じでしょうか。
指定回数を $limen に入れることで柔軟に繰り返し回数の条件を変更できます。
「同じ値が〇回続く」を if 文で判定するのではなく、内側のループ INNER_LOOP で現時点から1つづつカウンタを進めて1回1回判定していくようにしています。
値が同じであれば繰り返されているので、繰り返している回数を $reptation に増加していきます。
カウンタが指定回数まで達すると、条件を満たしたことを $is_recured に代入します。
外側のループ OUTER_LOOP の最後で $is_recured が真なら出力します。
出力の際はあらかじめ記録しておいた $repatation を使い、繰り返している回数分だけ出力します。
以下、例示します。
字下げに全角空白を用いてますのでコピペして試す場合は適宜削除して実行してください。
use strict;
my $data = <<'EOD';
#ヘッダー
0.00 2.0 11.5
0.01 6.3 17.2
0.01 2.1 14.2
0.01 1.2 14.3
0.01 2.1 14.3
0.01 3.7 14.3
0.01 3.7 14.3
0.01 4.1 14.3
0.06 4.1 14.3
0.01 4.1 14.9
0.01 4.1 14.9
0.03 4.1 14.8
EOD
# テキストデータを分割して各配列に入れる
my( @A, @B, @C );
foreach my $item ( split /\n/, $data ){
next if $item =~ /^#/ ;
my ($value_a, $value_b, $value_c ) = split / /, $item;
push @A, 0+$value_a;
push @B, 0+$value_b;
push @C, 0+$value_c;
}
my $limen = 5; # 条件となる繰り返し回数
my $array_length = @A; # @A の要素数
OUTER_LOOP:
for( my $idx = 0; $idx < $array_length; $idx++ ){
my $is_recured; # 繰り返し回数を満たしたかどうかを記憶する変数
my $reptation = 1; # 繰り返された回数。1回は必ず繰り返すので初期値は1
# 配列の最後まで次々と比較するループ
INNER_LOOP:
for( my $fore = 1; $idx + $fore < $array_length; $fore++ ){
# 値が同じなら繰り返し回数を増加
if( $A[ $idx ] == $A[ $idx + $fore ] ){
$reptation += 1;
}
# 値が異なればこのループを抜ける
else {
last;
}
# 条件回数に達したらフラグをセット
if( $reptation == $limen ){
$is_recured = 1;
}
}
# フラグが立っていれば、指定回数同じ値が続いているので出力
if( $is_recured ){
print "repeat same value $reptation times.\n";
for( my $i = 0; $i < $reptation; $i++ ){
print "$A[$idx+$i], $B[$idx+$i], $C[$idx+$i]\n";
}
print "----------------------\n";
}
}
__END__
実行結果
repeat same value 7 times.
0.01, 6.3, 17.2
0.01, 2.1, 14.2
0.01, 1.2, 14.3
0.01, 2.1, 14.3
0.01, 3.7, 14.3
0.01, 3.7, 14.3
0.01, 4.1, 14.3
----------------------
repeat same value 6 times.
0.01, 2.1, 14.2
0.01, 1.2, 14.3
0.01, 2.1, 14.3
0.01, 3.7, 14.3
0.01, 3.7, 14.3
0.01, 4.1, 14.3
----------------------
repeat same value 5 times.
0.01, 1.2, 14.3
0.01, 2.1, 14.3
0.01, 3.7, 14.3
0.01, 3.7, 14.3
0.01, 4.1, 14.3
----------------------
丁寧に回答していただき有り難うございました。
こ、こんなに長くなってしまうんですね。
頑張って参考にさせていただきます。
有り難うございました!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- Java Java 南京錠 2 2023/02/04 11:46
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- Excel(エクセル) Excelの関数についておしえてください。 3 2023/04/20 18:36
- 統計学 統計学、エクセルがわかりません!解答と詳しい解説をお願いします! (1)それぞれの地域別に記述統計量 9 2022/08/21 16:30
- C言語・C++・C# numpyスライス機能を使った数値計算 2 2023/05/08 16:01
- Visual Basic(VBA) 列と行の名前(重複あり)が交差するセルに、データを入力したい 2 2022/06/25 22:42
- その他(プログラミング・Web制作) pythonリストの特定の値を表示htmlで表示できない 2 2022/05/14 05:48
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
データベースから取得したデー...
-
index関数で複数個抜き出す
-
perlで2つの配列を比較する方...
-
VBのReturnの使い方
-
画面を強制的に再描画させる方法
-
範囲指定したセルを1つずつ飛...
-
VBAで3秒だけ時間を止めたい
-
VBAでの一時停止と再開の方法
-
DoEventsが必要な理由について
-
vbscriptでIE自動入力(途中で...
-
DOSコマンドのループ内のTIMEコ...
-
Escキーを押すと、中断する時と...
-
流れ図(フローチャート)が分か...
-
ハッシュマーク以降のアドレス取得
-
再帰関数のインライン展開
-
Excel vba でコンボボックスの...
-
リストボックスに縦スクロール...
-
UWSCに制限時間を付けたいです
-
vb.netです。2次元配列の要素を...
-
forループは何故、forなのですか?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
データベースから取得したデー...
-
perlで2つの配列を比較する方...
-
perlでファイルの拡張子を除い...
-
python質問
-
QNo.3258883データベースから取...
-
組み合わせを作るアルゴリズム
-
非共通要素を抜き出す
-
アルファベットn文字の組み合わ...
-
grep関数を用いた複数行からの抽出
-
複数の配列の要素を繰り返し処...
-
桁数指定と四捨五入
-
ハッシュのハッシュの値代入で...
-
サブルーチンへ渡した配列のリ...
-
index関数で複数個抜き出す
-
二次元配列のつかいかた。
-
正規表現 perl 連続ヒットの...
-
配列に入った変数を二度使いたい
-
プログラミングについて。 1つ...
-
画面を強制的に再描画させる方法
-
VBのReturnの使い方
おすすめ情報