先の質問「プログラムのヒントを下さい」でも扱ったのですが、
apple
best
apple
END
apple
beer
beer
END
zero
child
death
zero
のようなテキストから、ENDとENDの間か、ENDと最初もしくは最後の間の重複した文字列を取り除くスクリプトを書こうと思います。出力例は以下のようになってもらいたいです。
apple
best
END
apple
beer
END
zero
child
death
自分で頑張って下のコードまで書きましたが動きませんでした。特に、ENDと最初もしくは最後の間
の取り扱いがわかりません。どなたかご教授お願いいたします。
open(IN, "datafile");
@xx = <IN>;
@zz = ();
foreach $yy (@xx) {
if ($yy eq "end"){
@uniq = uniqArray(\@zz);
foreach my $value ( @uniq ){
print "$value\n";
}
@zz = ();
}else{
push(@zz,$yy);
}
}
close(IN);
sub uniqArray{
my $array = shift;
my %hash = ();
foreach my $value ( @$array ){
$hash{$value} = 1;
}
return(
keys %hash
);
}
No.3
- 回答日時:
「うまく動かない」というなら, 「何がどう『うまく動かない』のか」くらい書けない? 前のやつも「同一の単語が出現しているとエラーが起きてしまいました」で終わらせてるけど, 「どんなエラーが起きるのか」は書けるはずだよね (そもそも普通に考える限り「エラーが起きる」ことがありえないと思うのだが).
それくらいやってもバチはあたらないと思うよ.
本題に入ると, #1 で言われている「@zzには最後のEND以降の部分が残ってます。」というのは, 実際にやってみればすぐわかります. そのままでは「最後の END より後ろの部分」が出力されないはずです.
ただ, このプログラムは不自然. 自分だったら
sub uniqArray {
my %hash;
my @result;
foreach my $element (@_) {
unless ($hash{$element}) {
push @result, $element;
$hash{$element} = 1;
}
}
@result;
}
open my $fh, '<', 'datafile';
my @tmp;
while (my $line = <$fh>) {
chomp($line);
push @tmp, $line;
if ($line eq 'END') {
foreach my $element (uniqArray(@tmp)) {
print "$element\n";
}
@tmp = ();
}
}
foreach my $element (uniqArray(@tmp)) {
print "$element\n";
}
くらいかなぁ. #1 で言われるように, 表示するところまでサブルーチンにしそうだけど.
「動かない」とか「エラーが出る」とか答えてくれるのは全くかまわないけど, そういうときは最初に書いたように「どういう入力に対してどんな結果になることを期待したが実際に得られた結果はそれと違ってこんなふうになっている」とか, あるいはエラーが出るというならどんなエラーなのか, メッセージを完全に書いてほしい. それくらいの手間は惜しむものじゃないと思う.
回答ありがとうございます。以前にもエラーの内容もかくようにおっしゃられていたのを覚えています。
これからは、きちんとエラーの結果の内容も書こうとおもいます。アドバイスありがとうございました。
No.2
- 回答日時:
こんな感じですかね。
こういう問題はハッシュを使うと簡単ですよ。
インデントは全角スペースになっています。
#!/usr/bin/perl
use strict;
my %h;
while(<DATA>){
chomp;
if(/^END$/){
undef %h;
print "END\n";
}else{
if(not exists $h{$_}){
print "$_\n";
$h{$_} = 1;
}
}
}
__DATA__
apple
best
apple
END
apple
beer
beer
END
zero
child
death
zero
No.1
- 回答日時:
> open(IN, "datafile");
> @xx = <IN>;
INはここまでしか使わない(使えない)ので
> close(IN);
> if ($yy eq "end"){
「eq」は正しく「等しい文字列」の判定です。大文字小文字は区別されます。
'END' ne 'end' です
> foreach $yy (@xx) {
...
> }
このループが終わった段階で @zzには最後のEND以降の部分が残ってます。
ここでもう一度一連の処理(↓)が必要です。これもsubにしておいてもいいでしょう
@uniq = uniqArray(\@zz);
foreach my $value ( @uniq ){
print "$value";
# ← あと、 @xx=<IN>で読み込んだ文字列は改行コードまで含まれます。
#ここで\nを入れていると、改行が2つになります
#あるいは、\nはそのままにして、 foreach $yy (@xx) {の後で chomp $yy 等で改行コードを取り除くか。
}
回答ありがとうございます。残念ながら説明がよくわかりませんでした。
open(IN, "datafile");
@xx = <IN>;
close(IN);
@zz = ();
foreach $yy (@xx) {
chomp $yy;
if ($yy eq 'END'){
@uniq = uniqArray(\@zz);
foreach my $value ( @uniq ){
print "$value\n";
}
@zz = ();
}else{
push(@zz,$yy);
}
}
sub uniqArray{
my $array = shift;
my %hash = ();
foreach my $value ( @$array ){
$hash{$value} = 1;
}
return(
keys %hash
);
}
と直すところまではわかりました。しかし
> foreach $yy (@xx) {
...
> }
このループが終わった段階で @zzには最後のEND以降の部分が残ってます。
ここでもう一度一連の処理(↓)が必要です。これもsubにしておいてもいいでしょう
の意味がわかりません。
@zz = ();
で初期化しているのではありませんか?
# ← あと、 @xx=<IN>で読み込んだ文字列は改行コードまで含まれます。
#ここで\nを入れていると、改行が2つになります
#あるいは、\nはそのままにして、 foreach $yy (@xx) {の後で chomp $yy 等で改行コードを取り除くか。
とのことですが、
foreach $yy (@xx) {
chomp $yy;
if ($yy eq 'END'){
@uniq = uniqArray(\@zz);
foreach my $value ( @uniq ){
print "$value\n";
}
@zz = ();
}else{
push(@zz,$yy);
}
}
でよかったのでしょうか?
いずれにせよ、直してもうまくうごきませんでした。
どなたかアドバイスお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 稀に1円合いません? Sheet1から金額と個数を貼り付ける下記コードで、金額を切り上げるコードを何 3 2022/09/05 15:11
- Visual Basic(VBA) まとめシートから集計シートへA列のコードが一致したら1行コピーするマクロをネット上で見つけました。こ 1 2022/08/30 14:11
- Excel(エクセル) B列に文字がはいったらA列に数字が入るマクロードを完成させたい 4 2023/04/21 01:58
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Excel(エクセル) なぜExit Subがあるのかわかりません 4 2023/02/19 12:34
- Visual Basic(VBA) 今日の日付が過ぎたらその行を削除したい 1 2023/04/01 20:06
- Visual Basic(VBA) Excel VBAの解読について質問があります。 概要は、マクロでチェックボックスにチェックすると日 1 2023/02/10 07:50
- Visual Basic(VBA) Excel VBA ユーザーフォーム 複数のユーザーフォームの閉じ方。 2 2022/04/27 11:29
- Visual Basic(VBA) エクセル VBA 難しいです 1 2023/02/21 15:39
- Visual Basic(VBA) excel2021で実行できないマクロ。どこを直したらいいのか 2 2022/03/28 03:40
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
テキストファイルで提出とは?
-
perlで2次元配列をサブルーチ...
-
perlでリテラル値はメモリにど...
-
INDIRECT 横に再度抽出したい
-
Perl 重複カウント 上位3名
-
アルファベットに付いて質問し...
-
#!/usr/bin/perlで書きだしたCG...
-
Perlのエラーについてご教授く...
-
perlのflock関数でロックをかけ...
-
AI sisterとは、偽物の人ですか?
-
bashスクリプト
-
perlプログラミング 空白行削除
-
perlについて
-
perlのrequireの動き方について...
-
perlの構文でカンマの意味が分...
-
perlについての質問
-
perlのプログラミング 部分入れ...
-
perlをバージョンアップしたら...
-
Perl の外部モジュールの利用方法
-
perl このテキストファイルを簡...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
INDIRECT 横に再度抽出したい
-
perlをバージョンアップしたら...
-
openした後、closeしないでプロ...
-
Perlで特定文字列から特定文字...
-
Wallpaper Engineでおすすめの...
-
Perlのエラーについてご教授く...
-
アルファベットに付いて質問し...
-
Strawberry Perl for Windows ...
-
bashスクリプト
-
テキストファイルで提出とは?
-
Perl の外部モジュールの利用方法
-
#!/usr/bin/perlで書きだしたCG...
-
Windows10においての『Perl』の...
-
perlのflock関数でロックをかけ...
-
perlで2次元配列をサブルーチ...
-
Perlで時間の計算
-
perlのrequireの動き方について...
-
画像が表示でnull; this.src
-
ターミナルで特定の文字と文字...
-
英数文字列のうちの数値を4桁に...
おすすめ情報