• ベストアンサー

いくつかのファイルの一致を確認するプログラミングの作り方。

いくつかのファイルの一致を確認するプログラミングの作り方。 例えば7個のtxtファイル a, b, c, d, e, f, g があるとします。 a, b, c, d, e, f, g はそれぞれのファイルのファイル名です。 そのうち、 a, b, g のファイルの内容が全く同じであった場合、 a, b, g は一致していると判断するには、どんなプログラムを作成すればよいのでしょう? ちなみにファイルの中身は 数字が配列のように並んでおり、文字数は5000文字程度です。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

単純な方法) 各ファイルを逐次比較。aとb,c,d,e,f,gを比較し、bとc,d,e,f,gを比較し、cとde,e,f,gを比較し...というのをfまで繰り返す。一致を発見したら随時記録するか表示するかする。 ファイルの平均サイズをnとしたら、比較にかかる計算時間はO(n)なので、m個のファイルを逐次比較するのにかかるコストはO(n*m^2)。 fstatなどでファイルサイズを取得して、ファイルサイズが一致するもののみ比較すると、すべてファイルサイズが違う場合がおそらく最良のケースで、O(m^2)で調査可能。 さらに、前の調査で一致している場合は調査済みとマークするなどして飛ばすようにすると、すべて同じファイルだったときに最良で、計算時間はO(n*m)。 一致するものが少ない時に有効な方法) まず、各ファイルのチェックサムを計算。チェックサムを二分木に入れて、一致したものがあった場合は対応するファイル名を記録、後で対応表にあるファイルのみ比較する。 ファイルサイズをnとすると、ファイルのチェックサムを計算する計算時間はO(n)なので、m個のファイルのチェックサム計算時間はO(n*m)。 m個のファイルに付いて二分木を使って1つを比較する計算時間はO(log m)なので、m個これをやるとO(m log m)。 次に、対応表にあるファイルの比較の計算時間を考えると、最悪時はすべてが一致しているケースでO(n*m^2)。この場合、比較に律速されるのでO(n*m^2)が計算時間のオーダーとなる。最良はすべてが一致していないケースで、この場合は比較について計算する必要はない。この倍、計算時間のオーダーはmに比べてよほどnが小さくない限り、O(n*m)。 こう考えると、ファイルサイズについて二分木を使った比較をして、残ったものがしきい値以上だったらチェックサムで比較をし、それで一致した場合は実際のファイルで比較するというのが滅多に一致するファイルがない場合に効率的でしょうか。 逆に、ほとんど同じファイルしかない場合は、上で書いた単純な方法で、一致した場合はマークをして飛ばすというのが一番効率がいいと思います。

s3104s
質問者

お礼

皆様へ お早い解答、ありがとうございます。 C言語の質問をしたのは初めてだったので 質問に不足な点もあったかとは思いますが 伝えることが出来たので良かったです。 これは学校とは全く無関係ですので 宿題を皆様に問いかけたのではないんです。 そう受け取られたにも関わらず 解答してくださって感謝しています。 アドバイス等もありがとうございます。 今後、参考にしていきたいとおもいます。

その他の回答 (2)

回答No.2

一応確認だけど、これって学校の宿題をやらせようってわけじゃじゃないよね? (1)各ファイルのハッシュ値を算出。 (2)ハッシュ値が同じものは内容も同じ。 (3)内容が同じものをリストアップ。 (4)結果を表示。 ハッシュ値に関してはGoogleで調査してね。 こんなとこかな。

s3104s
質問者

お礼

お早い解答ありがとうございます。 C言語の質問は初めてだったので 質問に不足する点があったとは思うのですが 伝えることが出来たので良かったです。 これは学校とは全く無関係ですので 宿題を皆様に問いかけたのではないんです。 そう受け取られたにも関わらず 解答してくださって感謝しています。 アドバイス等もありがとうございます。 今後、参考にしていきたいとおもいます。

  • D400V
  • ベストアンサー率38% (17/44)
回答No.1

言語を書かないとレスが付かないかも。 あと、質問する場所もプログラミングにしないと専門職の方が見てくれないかもです。

s3104s
質問者

お礼

お早い解答ありがとうございます。 C言語の質問は初めてだったので 質問に不足する点があったとは思うのですが 伝えることが出来たので良かったです。 これは学校とは全く無関係ですので 宿題を皆様に問いかけたのではないんです。 そう受け取られたにも関わらず 解答してくださって感謝しています。 アドバイス等もありがとうございます。 今後、参考にしていきたいとおもいます。

関連するQ&A

  • リストファイルと一致する行の抽出

    2つのファイルがありまして、list.txtでリストアップしたキーワードに一致するinput.txt一行目の行を抽出したいです. fgrep -f list.txt input.txt ではout of memoryで行えません。 他に何かいい方法がありませんでしょうか? あれば教えていただきたいです。 list.txtはsortせずにこの順序を維持したいです。 <list.txt> d c a h g x k . . <input.txt> a 12 43 .. b 29 44 .. c 12 66 .. c 33 55 .. d 44 55 ..

  • リストファイルに一致する個数のカウントについて

    以下にリストファイルと、インプットファイルがあります。 リストファイルのそれぞれにインプットファイルの中で何個一致するかを出力させたいです。 目的にかなうawkや perlなどのスクリプトを教えてほしいです。 list.txt a b c d ・・ input.txt 1 a b c 2 a d 3 4 b c ・・ output.txt a 2 b 2 c 2 d 1 ・・

  • ディレクトリ内の全てのファイルの中身を操作したい

    ディレクトリ内に、例えば10個のテキストファイル a.txt b.txt c.txt d.txt e.txt f.txt g.txt h.txt i.txt j.txt があり、その中身にそれぞれ 2 6 98 65 4 52 98 100 82 56 という数字が書かれているとします。 これらのファイルの中身の平均をawkを用いたコマンドで表示させたいのですが、自分なりに頑張ったのですが実行できませんでした。 (cat * | awk'{BEGIN{total += $0; i += 1}END{print total/i}' のような感じで) どうすれば実行できるのか、よろしければお教えください。

  • PostgreSQL、外部ファイルからDBへの振り分け反映の方法

    PostgreSQL、外部ファイルからDBへの振り分け反映の方法 早速ですが質問させて頂きます。 『外部ファイル.txt』内容 ------ここから------ A B C D E F G H I 1 2 3 4 5 6 7 8 9 2 3 4 5 6 7 8 9 1 3 4 5 6 7 8 9 1 2 B C D E F G H I A 4 5 6 7 8 9 1 2 3 5 6 7 8 9 1 2 3 4 ------ここまで------ 上記のようなスペース区切りの文字ファイルがあるとして、このファイルのデータを 英字から始まる行はtable1へ、数字から始まる行はtable2へと振り分けたいです。 現在、1つのテーブルに反映させることは以下のコマンドを使用することにより可能なのですが、 2つのテーブルに振り分ける方法は全く思い浮かびません。 1つのテーブルに反映させる方法 \COPY table1 from 'C:\\~ファイルパス~\\外部ファイル.txt' delimiters ' ' null '' 下記のようなファイル内容でもかまいません。 ------ここから------ A B C D E F G H I -------------------- 1 2 3 4 5 6 7 8 9 2 3 4 5 6 7 8 9 1 3 4 5 6 7 8 9 1 2 -------------------- B C D E F G H I A -------------------- 4 5 6 7 8 9 1 2 3 5 6 7 8 9 1 2 3 4 ------ここまで------ あるいは ------ここから------ A B C D E F G H I -------------------- 1 2 3 4 5 6 7 8 9 2 3 4 5 6 7 8 9 1 3 4 5 6 7 8 9 1 2 ------ここまで------ わかる方がいらっしゃいましたらご回答いただければと思います。 また、出来ないようであれば何か参考になりそうな情報を教えていただければありがたいです。 PostreSQLのバージョンは8.2?です。 不足している情報がありましたら指摘してください。 以上です、お手数かけますがよろしくお願いいたします。

  • c言語  2つのファイルを行ごとに読み込むプログラミング

    c言語  2つのファイルを行ごとに読み込むプログラミング 0.txt と 1.txt という2つのテキストフォルダがあり 0.txt の中身は a a b b 1.txt の中身は c c d d というものとします。 これら2つのフォルダを読み込むとき まず1つのフォルダの1行目(a a)を表示し 他方の1行目(c c) 2行目(d d)を表示させて 続いて1つのフォルダの2行目(b b)を表示し 他方の1行目(c c) 2行目(d d)を表示させたいのです。 つまり実行結果が a a c c a a d d b b  ←理想の実行結果です c c b b d d となるようにしたいのですが #include <stdio.h> #include <stdlib.h> #define STR_MAX 256 int main(void) { FILE *fp, *fp2; int i, j, k; char buf[STR_MAX]; char buf2[STR_MAX]; fp = fopen("0.txt", "r"); fp2 = fopen("1.txt", "r"); if (fp == NULL && fp2 == NULL){ printf("\n"); } while(fgets(buf, STR_MAX, fp) != NULL){ while(fgets(buf2, STR_MAX, fp2) != NULL){ printf("%s%s", buf,buf2); } printf("\n"); } fclose(fp); fclose(fp2); return 0; } このプログラミングの実行結果は a a c c a a d d となり、0.txtの2行目(b b)は表示されません。 おそらく while 文 を2重にすることで 不具合が起きているのだと思うのですが 色々と調べた結果、これ以外に プログラミングが思いつきません。 私の理想の実行結果にするためには どこを訂正させると良いのでしょうか? 恐れ入りますが ご回答 どうかよろしくお願いいたします。

  • 2ファイルの比較

    2ファイルの比較 中身が以下のようなファイルがあります。 ---ファイルA中身--- a c c d e f f ----------------- ---ファイルB中身--- a a b b b c d e g ----------------- この2ファイルから、以下のようなファイルを作りたいです。 ---ファイルC中身--- b b g ----------------- つまり、ファイルBにはあって、ファイルAにはない行をファイルCに入れたいです。 while($line_B = <FILEB>){ while($line_A = <FILEA>){ @A = split(/,/,$line_A); if($line_B !~ /$line_A/){ print FILEC $line_B; } } seek(FILEA,0,0); } としてみたのですが、全然ダメです。理由も分かってます。 が、お手上げです。ご教授お願いします。

  • ファイルから一行ずつ読み込むとき、@F[0] と $_ は違う?

    データファイルを一行ずつ読み込んで、文字列を一文字ずつコンマ区切りにしたいと思っています。たとえば、   xyz → x,y,z としたいと思っています。 今、data.txt に  abc  defgh という2行が書いてあります。  perl -nla -e '@chars= split(//,@F[1]); print join(",",@chars);' data.txt とすると  a,b,c  d,e,f,g,h という出力が無事に得られました。 どうせ、data.txt は一列しか使っていないので、 @F[0] の代りに $_ を使ってみました。  perl -nle '@chars= split(//, $_); print join(",",@chars);' data.txt しかし、結果は  a,b,c,  d,e,f,g,h, のように、各行の最後に余計なコンマが付いてしまいます。 なぜでしょうか? 一列しかデータがないので、@F[0] と $_ は同じだと思っていたのですが、なにか違うのでしょうか?

    • ベストアンサー
    • Perl
  • ファイル出力について。

    こんにちわ。 String型配列に格納した文字列5つを、それぞれ改行し、 ファイルに出力したいのですが、やり方がわかりません。 例: String[] test = new String{"a","b","c","d","e"}の場合 ↓test.txtの内容 --------- a b c d e --------- わかる方いらっしゃいましたら、ご教授願います。 宜しくお願いします。

    • ベストアンサー
    • Java
  • batファイルについて

    C:\work\a\a.txt C:\work\a\b.txt C:\work\a\c.txt C:\work\b\a.txt C:\work\b\d.txt C:\work\c\a.txt C:\work\d\a.txt C:\work\d\e.txt C:\work\d\f.txt 上記のようなファイルがあったとき 各ディレクトリのa.txtだけを残したいのですが (他のファイルは全部削除) どのようなbatファイルを作成すればよろしいのでしょうか。 すみませんが方法がありましたら教えてください。

  • C言語のプログラミング問題(難解)について

    C言語のプログラミング問題(難解)について教えてください! C言語の勉強し始めましたが次の問題のプログラミングが分かりません 分かる方がいましたらよろしくお願いします。 以下の問題です。 次の作業を実現するためのプログラミングを描け。 機能名:リストファイルの分割処理 ■概要:部門1、部門2の商品が混合して書かれたファイルがある。 部門毎に分けたファイルを新たに作成する。 ■条件 (1)ファイルを1行ずつ読み込み、ポインタで受け取り関数で渡すこと。 (2)出力ファイルの最終行には各部門の品種数を入力すること (3)出力ファイルは固定長とし、空きが出る場合は半角スペースでレコード長を合わせること。 (4)エラー発生時にはエラーメッセージを表示し、終了すること。 ■ファイルレイアウト(入力ファイル) レコード長:26(固定長) 長さ 項目名 1 |部門コード1 1 |(区切り文字カンマ) 6 |商品名1 1 |(区切り文字カンマ) 1 |部門コード2 1 |(区切り文字カンマ) 6 |商品名2 1 | (区切り文字カンマ) 1 |部門コード゛3 1 |(区切り文字カンマ) 6 | 商品名3 ■ファイルレイアウト(出力ファイル) レコード長:20(固定長) 長さ | 項目名 6 |商品名1 1 ||(区切り文字カンマ) 6 |商品名2 1 ||(区切り文字カンマ) 6 |商品名3 (1)入力ファイル(LIST_INPUT.txt) 1,菓子A,1,菓子B,1,菓子C 2,野菜A,2,野菜B,2,野菜C 1,菓子D,1,菓子E,2,野菜D 1,菓子F,1,菓子G,2,野菜E 1,菓子H,2,野菜F,1,菓子I 1,菓子J,1,菓子K,2,野菜G (2)出力ファイル1(菓子)(LIST1.txt) 菓子A,菓子B,菓子C 菓子D,菓子E,菓子F, 菓子G,菓子H,菓子I 菓子J,菓子K 11 (3)出力ファイル2(LIST2,txt) 野菜A,野菜B,野菜C 野菜D,野菜E,野菜F 野菜G 7 *出力ファイルの最終行に品種数を追加すること。 よろしくお願い致しますm(__)m