![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
現在perlを勉強中の身です。
1行に1英単語があり、それが100~200行に渡ってあるファイルがあります。
このファイルの単語に重複しているものはありません。Xとします。
また別のファイルにも同様に1行に1英単語があり、それが100~200行に渡ってあるファイルがあります。
このファイルの単語は重複しているものがあります。Yとします。
当然、最初のファイルにある単語もない単語もあります。
ファイルXから単語を読み取りYでその単語が何回出現したかチェックして単語と出現回数を出力するようなプログラムを組みたいと考えています。
参考書やインターネットで調べたところ、単語を数えるプログラム等はあるのですが、ファイルを読み込みさらにファイルを読み込んで比較する、といった流れのプログラムを見つけることができませんでした。
遠回りな考え方だと
例えば
ファイルX
a b c d(本当は単語間は改行があり1行1単語なのですが、見やすさのためにこのように表記しました。)
ファイルY
c c d e f
とあった場合まず二つのファイルを結合し
ファイルZ
a b c d c c d e f
として二回以上出現した単語のみを抜き出し
ファイルZ'
c 2
d 1 (この時出現回数を-1回する)
としてファイルXと結合して出現回数を足して-1すると
ファイルX'
a 0
b 0
c 2
d 1
のようにできるのではないかと考えてはいます。しかし遠回り過ぎてスマートではないように感じます。
どのような考え方、そしてどのようなプログラムを組めばよいのでしょうか。ご教授お願い致します。
No.3ベストアンサー
- 回答日時:
1対nマッチングを応用してもできるのではないかと思います。
まず、前提として、
1.1行に重複していない1英単語だけのファイルを「xxx.txt」とします。
2.1行に重複している可能性のある1英単語だけのファイルを「yyy.txt」とします。
3.上記2つのファイルの英単語は昇順に並んでいるものとします。
4.「xxx.txt」と「yyy.txt」の両方にある英単語については「英単語と出現件数」を出力します。
5.「xxx.txt」だけにある英単語については「英単語と出現件数(結果として0)」を出力します。
6.「yyy.txt」だけにある英単語については何も出力しません。
7.4と5での出力ファイルを「zzz.txt」とします。
とします。
上記の前提で作成したのが以下のサンプルです。
---------------------------------------------------------------------------------
# ファイルのオープン
open(IN1,"xxx.txt"); #マスターファイル
open(IN2,"yyy.txt"); #トランザクションファイル
open(OUT1,">zzz.txt"); #出力ファイル
# 初期値設定
$high_value = pack("h8","ffffffff"); #終了判定
$in1_key = undef; #マスタキー
$in2_key = undef; #トランザクションキー
$occur_ctr = 0; #出現回数
# 1件目のデータ入力
s_in1();
s_in2();
# 主処理
until ($in1_key eq $high_value && $in2_key eq $high_value) {
# マッチングの時(両方のファイルにデータがある)
if ($in1_key eq $in2_key) {
until ($in1_key ne $in2_key) {
$occur_ctr++;
s_in2();
}
$out1 = join("\t",$in1_key,$occur_ctr);
print OUT1 "$out1\n";
s_in1();
$occur_ctr = 0;
}
# マスタオンリーの時(マスタファイルだけにデータがある)
elsif ($in1_key lt $in2_key) {
$out1 = join("\t",$in1_key,$occur_ctr);
print OUT1 "$out1\n";
s_in1();
}
# トランザクションオンリーの時(トランザクションファイルだけにデータがある)
elsif ($in1_key gt $in2_key) {
s_in2();
}
}
# マスタファイル入力
sub s_in1 {
if ($line1 = <IN1>) {
chomp($line1);
$in1_key = $line1;
}
else { #マスターファイルが終了のとき
$in1_key = $high_value;
}
}
# トランザクションファイル入力
sub s_in2 {
if ($line2 = <IN2>) {
chomp($line2);
$in2_key = $line2;
}
else { #トランザクションファイルが終了のとき
$in2_key = $high_value;
}
}
# ファイルのクローズ
close(IN1);
close(IN2);
close(OUT1);
---------------------------------------------------------------------------------
※なお、カラムをそろえるために、全角スペースを使っていますので、
このままコピー・ペーストしても動作しません。この点はご注意ください。
回答ありがとうございます。連想配列について勉強し、どうしてもできなかった時に参考にさせて頂きます。わざわざプログラムまで書いて頂いてありがとうございました。
No.5
- 回答日時:
「連想配列にキーが存在するかどうか」を判定するなら, 一般には defined より exists の方が適切です>#4. defined を使うと「値が存在しない」場合だけでなく, 「値が undef である」場合にも偽になります. これに対し exists なら前者の場合のみ偽になります.
もちろん今の場合には「値が undef であるようなキー」を作らないからどっちでも同じことだし, もっとはっきり言えば「そもそも definedness の判定すら不要」だったりしますが.
No.4
- 回答日時:
この例で連想配列(ハッシュ)使うときに注意するのは「Yにだけ存在する単語」の時ですね。
$h{key}で、連想配列にkeyが無い時は未定義値になるので、definedで判定できます。
No.2
- 回答日時:
Xの各行を読み込んでいき、連想配列(ハッシュ)のキーにする。
値は0。Yの各行を読み込んでいき、その行の単語をキーにして連想配列の項目を指定し、値を1加算。
最後に連想配列全体を出力。
これが一番わかりやすい方法です。
やろうとしていることのレベルを考えると、プログラムを全部教えてしまったら意味がないので書きません。
連想配列について調べてください。
https://www.google.com/search?q=Perl+%E9%80%A3%E …
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Word(ワード) パソコン内にあるwordファイルを探したいです。word内に、ある単語が利用されている(書かれている 1 2022/10/11 16:38
- Excel(エクセル) 配列操作について 5 2023/04/18 07:27
- UNIX・Linux テキストファイルをページ番号付きでコマンドラインから印刷したい 1 2023/02/22 12:47
- C言語・C++・C# 至急お願いします。C言語で.imgのファイルを読み込んで1バイトづつ出力するプログラムを作りたいので 3 2023/01/16 22:49
- 大学受験 大学受験 英単語について こんにちは、現在底辺から逆転合格したいと思ってる 受験生です。 英単語につ 2 2022/10/16 17:16
- 大学受験 大学受験英語の勉強法についてです どうしても英語長文の勉強ができません 初めて数分で絶対にやる気がな 2 2023/05/05 00:32
- Excel(エクセル) 【マクロ】ファイルを古い順に、1個ずつ移動する 1 2022/09/06 20:30
- 大学受験 英単語帳について質問です。 たくさんの回答お待ちしております。 現在高3、産近甲龍志望です。 現在タ 5 2023/08/21 11:50
- PHP 画像ファイルの名前をそのままURLにする 3 2022/10/16 11:18
- 英語 英語勉強 4 2022/07/14 21:01
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
多数のサブディレクトリ内のフ...
-
VBAでワークシートを引数として...
-
拡張子を元に戻す
-
バッチ処理でファイルの中身を...
-
.txtではなく.logの方が良いの...
-
ファイルの最後に文字列挿入
-
renameコマンドについて
-
forfilesで検索したファイルを...
-
Windowsのバッチファイルを利用...
-
ファイル内容の修正、行削除に...
-
javaで大量のファイルを読み込...
-
バッチファイル 複数ファイル...
-
テキストファイルで提出とは?
-
コマンドプロンプトでファイル...
-
COPYコマンドで結合すると余計...
-
複数のテキストファイルを1つに...
-
Teraマクロで取得した変数を編...
-
テキストファイルの結合+改行に...
-
エクセルの各セルの内容をそれ...
-
VBSで、テキストファイルに対し...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バッチ処理でファイルの中身を...
-
VBAでワークシートを引数として...
-
.txtではなく.logの方が良いの...
-
拡張子を元に戻す
-
多数のサブディレクトリ内のフ...
-
COPYコマンドで結合すると余計...
-
ファイルの最後に文字列挿入
-
Windowsのバッチファイルを利用...
-
バッチファイル 複数ファイル...
-
renameコマンドについて
-
psqlでエラーログをとりたい
-
テキストファイルで提出とは?
-
forfilesで検索したファイルを...
-
VBAでエクセルをtxtに変換する...
-
テキスト(txt)→ワード(docx)へ...
-
UWSCでテキストファイルを開い...
-
バッチファイルで文字列削除に...
-
wikiでローカルファイルのリン...
-
ExcelVBA テキストファイルUNIC...
-
コマンドプロンプトで指定した...
おすすめ情報