2

テキスト ファイルを読み取り、単語数、個別の単語数、および C で最も頻繁に使用される単語を出力するコードを作成する必要があります。

単語数を出力するコードは既に作成しましたが、個別の単語数または最も頻繁に使用される単語を見つける方法がわかりません。strcmp を使用することになっていることはわかっていますが、そうする方法がわかりません。どんな助けでも大歓迎です。これが私がこれまでに持っているものです。

int main(int argc, char *argv[])
{
    int number=0;
    char temp[25000][50];
    char word[25000][50];
    char *word2[25000][50];
    int wordCount=0;
    int distinctCount=0;
    FILE *fp;

    //reads file!
    fp = fopen("COEN12_LAB1.txt", "r");

    if(fp == NULL)
    {
        printf("File Missing!\n");
        return 0;
    }

    //counts words in file!
    while(fscanf(fp,"%s", word) == 1)
        wordCount++;

    printf("Total number of words: %d\n", wordCount);
    fclose(fp);`
}
4

4 に答える 4

1

最初に、異なる単語を効率的に保持できる構造を実装する必要があるでしょう。ハッシュ テーブルは、可能なものの 1 つです (おそらく最適です)。

C でのハッシュの実装と使用例を次に示します。

また、この質問を調べることもできます: Porting std::map to C?

于 2013-09-27T23:01:20.737 に答える
0

単純なデータベースを使用して、入力テキストからさまざまな単語数を計算できます。簡単にするために、SQLiteを使用することをお勧めします。以下に、いくつかのサンプル コードを追加しました (簡潔にするために、エラー処理は省略しました)。

単語を読むために、fgets. 入力ファイルからの実際の行を保持するのに十分な大きさのバッファが常に確保されている限り、このアプローチはうまく機能することに気付きました。それ以外の場合、単語はバッファの最後で分割され、何らかの方法で処理する必要があります。

私が使用したテキストを解析するためにstrtok. 実装中に、単語区切り文字を正しく設定するのは非常に難しいことがわかりました。これに加えて、可能性のあるスペルの違い (大文字化など) と、他の点では等しい単語の語形変化は、このアプローチでは完全に無視されるため、結果に悪影響を与える可能性があります。

データがデータベースに格納されると、クエリ言語はクエリを作成して最大 (個別) 単語数または単語頻度を取得するのに非常に適しています。したがって、この柔軟なアプローチは、入力テキストから複数の統計を計算する場合に利点があると思います。C ですべての特殊なケースを実装する必要がないためです。テストのために、SQLite に関するウィキペディアの記事の一部をファイルwords.txt.

次に例を示します。

#include <sqlite3.h>
#include <stdio.h>
#include <string.h>

#define DELIM " \r\n\t,.-;:_#+*\\=)(/&%$§\"“”!1234567890}][{'"
#define BUFSIZE 4096
#define SQLSIZE 256

int print_row(void* p, int ncols, char **values, char **names) {
    for (int i = 0; i < ncols; i++)
        printf("| %15s : %15s %s", names[i], values[i], i<ncols-1?"":"|\n");
    return 0;
}

int main(int argc, char * argv[]) {
    /* open infile */
    FILE * infile = fopen("words.txt", "r");
    /* initialize database */
    sqlite3 *db_handle = 0;
    sqlite3_open(":memory:", &db_handle);
    sqlite3_exec(db_handle, "CREATE TABLE word (word TEXT);", 0, 0, 0);
    /* parse file, populate db */
    char buf[BUFSIZE], sql[SQLSIZE], *word;
    while(fgets(buf, BUFSIZE, infile))
        for (word = strtok(buf, DELIM); word != 0; word = strtok(0, DELIM)) {
            snprintf(sql, SQLSIZE, "INSERT INTO word VALUES ('%s');", word);
            sqlite3_exec(db_handle, sql, 0, 0, 0);
        }
    /* count of words */
    sqlite3_exec(db_handle,
                 "SELECT COUNT(word) AS total_words FROM word;",
                 print_row, 0, 0);
    /* count of distinct words */
    sqlite3_exec(db_handle,
                 "SELECT COUNT(DISTINCT word) AS distinct_words FROM word;",
                 print_row, 0, 0);
    /* top five most frequent words */
    sqlite3_exec(db_handle,
                 "SELECT word, COUNT(*) AS count FROM word "
                 "GROUP BY word ORDER BY count DESC LIMIT 5;",
                 print_row, 0, 0);
    sqlite3_close(db_handle);
}

ここに私の出力があります:

$ gcc test.c -std=c99 -lsqlite3 && ./a.out 
|     total_words :             561 |
|  distinct_words :             314 |
|            word :          SQLite |           count :              17 |
|            word :              is |           count :              16 |
|            word :             the |           count :              15 |
|            word :               a |           count :              14 |
|            word :              to |           count :              12 |

参考のため:

于 2013-09-29T21:09:34.993 に答える