• ベストアンサー

重複番号出力方法について

こんばんは。 大変お世話になっています。 このコミュニティーでの質問ではないかもしれませが・・・ テキストファイルに出力された、1番から10000番までの番号の中で重複している番号を抜き出すツールや方法はありますでしょうか? また、プログラムとして、記述可能でしょうか? よろしくお願い致します。

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

★プログラムとして記述するのですか? ・ソートされたデータならば、もしくはソートできるデータならば簡単に重複行をカットまたは、抽出できます。 ・でも、データ位置を保存したままで重複行をチェックするには少し工夫が必要です。 ・一番簡単な重複行チェックのアルゴリズムを教えます。 ●アルゴリズム(一例) ・テキストファイルを行単位でメモリへ格納します。→10,000行 ・メモリへ格納した行データは、文字列のポインタ配列で管理します。 ・この配列を『qsort』などでソートします。分かりますか? ・そしたら、1行目から順番に次の行データが『重複』している番号かをチェックします。 ・チェックした結果、同じ番号ならばその行を『抜き出す』処理をします。 ●サンプル(一例) void main( void ) {  char *alloc;  char *line[ 20000 ]; ←テキストの最大行数(2万行)  char buff[ 1024 ]; ←1行の最大バイト数  int max = 0;  int now;  FILE *fp;    if ( (fp = fopen("filename.txt","r")) != NULL ){   while ( fgets(buff,sizeof(buff),fp) != NULL ){    if ( (alloc = malloc(strlen(buff) + 1)) == NULL ){     printf( "メモリ不足です.\n" );     break;    }    if ( max >= 20000 ){     printf( "行数が多すぎます.\n" );     break;    }    line[ max++ ] = strcpy( alloc, buff );   }   line[ max ] = NULL;   fclose( fp );      qsort( line, max, sizeof(char*), MySortComp ); ←ソート比較関数(自作しましょう)   MyDoubleExtract( line, max ); ←ここで重複行チェック(printfで出力)      for ( now = 0 ; now < max ; now++ ){    free( line[now] ); ←メモリ解放   }  } } 最後に: ・上記のサンプルは、テキストファイルを行単位で読み込む部分のみです。 ・ソート部分と、重複行チェックは質問者さんが作って下さい。→頑張ってね。 ・『MySortComp』関数は、ソートするときの比較関数です。→qsort関数の使い方を参照。 ・『MyDoubleExtract』関数が、重複行をチェックして出力する関数です。→上記のアルゴリズム参照。 ・以上。おわり。

参考URL:
http://www.bohyoh.com/CandCPP/FAQ/FAQ00047.html
bird0214
質問者

お礼

こんばんわ。 返信ありがとうございます。 ソートはしていませんが、テキストファイルを1行ずつ読み込み、int型配列を用いて番号をいれ、重複箇所をチェックし、カウントするというプログラムを作りました。 Oh-Orangeさんのおっしゃるとおりの方法(ソートはできていませんが)で解決できました。 ありがとうございました。

その他の回答 (3)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.4

プログラムとして書くことができなければツールも存在しないわけで、 もちろん記述は可能です。 残念ながらひとつのツールで済ませることはできませんが、#1の方の仰るとおり 複数のツールを組み合わせて実現できます。 sort/uniq/sed はUNIXであれば間違いなくあるはずですが、Windowsでも 移植されたものや同等のものがあります。 またプログラムを書くとして、それはCまたはC++で書くことが必須なのでしょうか? awkだとかPerl/Ruby/Pythonといったものを使って済ませることができます。 これもUNIXならほぼインストールされていると考えられますし、Windowsでも 移植されているものがあります(それをインストールする手間がありますが)。 1~10000の番号がどのようにテキストファイルに置かれているのかが不明なのですが、 一行にひとつの番号という前提を置いていいなら awkで { numbers[$1]++ } END { for (i in numbers) { if (numbers[i] > 1) print i } } 重複している番号を抜き出せばいいだけならこれだけです。 どれぐらい重複していたとか、番号順で並べたいというなら もうちょっと手間がかかりますがそんなに行数は増えません。 sortf (win)(Windows95/98/Me / ユーティリティ) http://www.vector.co.jp/soft/win95/util/se000882.html?site%3Dn コマンドラインツール - WindowsをUNIXっぽく http://qwerty777.s57.xrea.com/winunix/command.htm

bird0214
質問者

お礼

返信ありがとうございます。 1から10000までの番号順は1から10000まで、番号順にならんでいます。 Cでプログラムを作り解決することができました。 ありがとうございました。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

std::sortで整列してからstd::unique(またはstd::unique_copy)で重複要素を取り除くというのは?

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

どのように出力されているかとかどのような環境なのかにもよりますが, 「普通の UNIX の環境でかつ各行に 1個ずつ番号がある」という状況だと sort + uniq + sed でいけますね.

関連するQ&A