初めまして、説明がうまく伝わらないかもしれませんがよろしくお願いいたします。
同じ値が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ランキング
-
データベースから取得したデー...
-
grep関数を用いた複数行からの抽出
-
配列に入った変数を二度使いたい
-
正規表現 perl 連続ヒットの...
-
画面を強制的に再描画させる方法
-
ハッシュ検索はなぜ速い
-
VBのReturnの使い方
-
ハッシュのハッシュを実現したい。
-
リストボックスに縦スクロール...
-
乱数の桁数指定、または範囲指定。
-
Can't use string ("0") as an ...
-
GIFアニメをループさせたくない
-
文字列を変数名として扱う方法
-
アクティブセルから、A列最終行...
-
VB6の公式リファレンスはありま...
-
まったく同じファイルのハッシ...
-
エクセルの当番表を作っていま...
-
ループフリー
-
イベントの発生を待つ
-
Javaでゲーム
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
データベースから取得したデー...
-
perlで2つの配列を比較する方...
-
DBIを使ってのデータの取り出し...
-
python質問
-
perlでファイルの拡張子を除い...
-
grep関数を用いた複数行からの抽出
-
アルファベットn文字の組み合わ...
-
半角文字の縦書き表示
-
乱数と順列と組み合わせ
-
配列やハッシュで中身が同じか...
-
桁数指定と四捨五入
-
ループ中でのmy宣言と処理速度
-
画面を強制的に再描画させる方法
-
VBAで3秒だけ時間を止めたい
-
VBAでの一時停止と再開の方法
-
VBのReturnの使い方
-
どなたかこのプログラミングを...
-
Escキーを押すと、中断する時と...
-
UWSCの終了の仕方
-
エクセルの当番表を作っていま...
おすすめ情報