• ベストアンサー

C言語で以下のようなプログラムを作成してください

3つの文章X.txt,Y.txt,Z.txtでY,ZのうちどちらがXに近いか判定するプログラム。X.txtを読み込んでXに出現する単語からなる単語の木を作成する。次にY,Zを読み込み単語の木と単語の出現頻度をもとにXとY、XとZの類似度を測るための統計的データを計算する。そしてY,ZのどちらがXに近いか、とその根拠となる統計データを出力する。

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

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

文章の類似点を算出するようなアルゴリズムがあるらしいけど 単語の木とか難しいことはわからないので、とりあえず X.txtに出現する単語において、その出現数と、 Y.txt(Z.txt)における出現数を掛け算し、 その総和が大きい方を類似度の高い文章とすると、 #include <stdio.h> #include <string.h> #include <malloc.h> struct WordList { int count; /*出現数*/ char word[ 64 ]; /*単語文字列*/ }; /*単語リストを作成する*/ bool makeWordList( const char* fileName, WordList** list, int* listSize ) { FILE* stream = fopen( fileName, "r" ); if( !stream ) { return false; } char buffer[ 256 ]; /*1行は255文字まで*/ while( fgets( buffer, sizeof( buffer ), stream ) ) { const char sep[] = " ,.;:\"\'\t\r\a\n"; char* word = strtok( buffer, sep ); while( word ) { /*既に登録済みの単語を検索して見つかったら出現数+1*/ int ii; for( ii = 0; ii < *listSize; ii++ ) { if( !strcmp( ( *list )[ ii ].word, word ) ) { ( *list )[ ii ].count++; break; } } /*新しい単語の場合は単語リストに登録する*/ if( ii >= *listSize ) { *list = ( WordList* )realloc( *list, sizeof( WordList ) * ( *listSize + 1 ) ); memset( ( *list ) + *listSize, 0, sizeof( WordList ) ); ( *list )[ *listSize ].count = 1; strncpy( ( *list )[ *listSize ].word, word, sizeof( ( *list )[ *listSize ].word ) - 1 ); ++( *listSize ); } word = strtok( NULL, sep ); } } fclose( stream ); return true; } /*単語リストを破棄する*/ void removeWordList( WordList** list ) { if( *list ) { free( *list ); *list = NULL; } } /*単語リストから該当する単語を探す*/ int findList( WordList* list, int listSize, const char* word ) { for( int ii = 0; ii < listSize; ii++ ) { if( !strcmp( list[ ii ].word, word ) ) { return list[ ii ].count; } } return 0; } /*単語リストを比較する*/ int compareList( WordList* list1, int listSize1, WordList* list2, int listSize2, WordList* list3, int listSize3 ) { printf( "X.txtに出現する単語(数)\tY.txt出現数(point)\tZ.txt出現数(point)\n" ); int count2 = 0; int count3 = 0; for( int ii = 0; ii < listSize1; ii++ ) { /*単語の類似点=X.txtでの単語の出現数×Y.txt(Z.txt)での出現数とする*/ /*X.txtの単語について全て上記の計算を行い、総和を文章の類似度とする*/ int temp2 = findList( list2, listSize2, list1[ ii ].word ); int temp3 = findList( list3, listSize3, list1[ ii ].word ); printf( "%s(%d)\t%d(%d)\t%d(%d)\n", list1[ ii ].word, list1[ ii ].count, temp2, temp2 * list1[ ii ].count, temp3, temp3 * list1[ ii ].count ); count2 += list1[ ii ].count * temp2; count3 += list1[ ii ].count * temp3; } return count2 - count3; } int main() { WordList* listX = NULL; WordList* listY = NULL; WordList* listZ = NULL; int listSizeX = 0; int listSizeY = 0; int listSizeZ = 0; int result = 0; do { if( !makeWordList( "X.txt", &listX, &listSizeX ) ) break; if( !makeWordList( "Y.txt", &listY, &listSizeY ) ) break; if( !makeWordList( "Z.txt", &listZ, &listSizeZ ) ) break; result = compareList( listX, listSizeX, listY, listSizeY, listZ, listSizeZ ); if( 0 < result ) printf( "故にY.txtのほうが類似している\n" ); else if( 0 > result ) printf( "故にZ.txtのほうが類似している\n" ); else printf( "故に類似度は同じ\n" ); } while( false ); removeWordList( &listX ); removeWordList( &listY ); removeWordList( &listZ ); return 0; }

noname#136979
質問者

補足

プログラムを作成していただきありがとうございました。このプログラムですとtheやaのせいで誤差が生じるようなので単語長が5以上のものについてだけ表示するようなものを作っていただけませんか。

その他の回答 (1)

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

何を言われたのか全く理解できてないね?

参考URL:
http://okwave.jp/qa/q6865155.html