C言語関係掲示板

過去ログ

No.279.ファイルで使用頻度の高い3つの単語を表示

[戻る] [ホームページ]


No.1673

C++からCへ書き換えてもらいたいです
投稿者---ケイ(2002/06/07 02:04:27)


初投稿です。こんばんは。
english.txtという英単語のファイルを読み込んで使用頻度の高い3つの単語を表示するプログラムでC++のプログラムをCのプログラムへと書き換えてもらいたいのです。プログラムは、、、
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

const char *FILENAME = "english.txt";
const int MAXLEN = 4096;

class Word {
public:
string words;
int count;
Word(string str, int i = 1) { words = str; count = i; }
};

class IsinWord {
string str;
public:
IsinWord(string s) : str(s) {}
bool operator()(Word ws) {
return str == ws.words;
}
};

int wordcount = 0;
void insert_word(const char *str);
vector<Word> wds;

bool greaterCount(const Word &wa, const Word &wb)
{
return wa.count > wb.count;
}

int main()
{
char buf[MAXLEN], *p;
int i;

ifstream ifs(FILENAME);

if (!ifs) {
cerr << "ファイル'" << FILENAME << "'が見つかりません。" << endl;
exit(1);
}

while (1) {
if (!ifs.getline(buf, MAXLEN)) break;
p = strtok(buf, " ,.;:\n");
if (p == NULL) continue;
insert_word(p);
while ((p = strtok(NULL, " ,.;:\n")) != NULL)
insert_word(p);
}

cout << wordcount << "個の単語が見つかりました。" << endl;
cout << "上位3個を表示します。" << endl;

sort(wds.begin(), wds.end(), greaterCount);

vector<Word>::iterator wp = wds.begin();
for (i = 0; i < 3; i++, wp++) {
if (wp == wds.end()) break;
cout << "単語 = '" << wp->words << "', 出現回数 = " << wp->count << "回" << endl;
}
return 0;
}

void insert_word(const char *str)
{
vector<Word>::iterator p = find_if(wds.begin(), wds.end(), IsinWord(str));
if (p != wds.end())
p->count++;
else {
wds.push_back(Word(str));
wordcount++;
}
}
です。どなたか教えてください。お願いします。


No.1675

Re:C++からCへ書き換えてもらいたいです
投稿者---かずま(2002/06/07 08:29:34)


> C++のプログラムをCのプログラムへと書き換えてもらいたいのです。

なぜ、書き換えをしないといけないのでしょうか。教えてください。

vector&lt;Word&gt; wds; を単純に Word wds[3000]; と固定長配列にすれば
簡単ですが、vector のような拡張性は失われてしまいます。
Word *wds; にして、malloc, realloc を使えば、拡張は可能でしょうが、
コードが少し煩雑になります。

とりあえず、配列の範囲チェックもしない単純版だと、こうなりました。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char *FILENAME = "english.txt";
enum { MAXLEN = 4096 };

typedef struct {
    char *words;
    int count;
} Word;

void push_back(Word *wp, const char *str)
{
    wp->words = strdup(str);
    wp->count = 1;
}

int IsinWord(const Word *wp, const char *str)
{
    return strcmp(str, wp->words) == 0;
}

int wordcount = 0;
void insert_word(const char *str);
Word wds[3000];

int greaterCount(const void *a, const void *b)
{
    const Word *wa = a;
    const Word *wb = b;
    return wb->count - wa->count;
}

int main()
{
    char buf[MAXLEN], *p;
    int i;
    Word *wp;

    FILE *fp = fopen(FILENAME, "r");

    if (fp == NULL) {
        fprintf(stderr, "ファイル'%s'が見つかりません。\n", FILENAME);
        exit(1);
    }

    while (1) {
        if (!fgets(buf, MAXLEN, fp)) break;
        p = strtok(buf, " ,.;:\n");
        if (p == NULL) continue;
        insert_word(p);
        while ((p = strtok(NULL, " ,.;:\n")) != NULL)
            insert_word(p);
    }

    printf("%d個の単語が見つかりました。\n", wordcount);
    printf("上位3個を表示します。\n");

    qsort(wds, wordcount, sizeof(*wds), greaterCount);

    wp = wds;
    for (i = 0; i < 3; i++, wp++) {
        if (wp == wds + wordcount) break;
        printf("単語 = '%s', 出現回数 = %d回\n", wp->words, wp->count);
    }
    return 0;
}

void insert_word(const char *str)
{
    Word *p;
    for (p = wds; p < wds + wordcount; p++)
        if (IsinWord(p, str))
            break;
    if (p != wds + wordcount)
        p->count++;
    else {
        push_back(wds + wordcount, str);
        wordcount++;
    }
}


No.1677

質問範囲が広すぎます
投稿者---B.Smith(2002/06/07 13:59:13)


すでに回答いただいているようですので、私からは回答はしませんが、今後のこともあるので一応忠告しておきます。

>初投稿です。こんばんは。
>english.txtという英単語のファイルを読み込んで使用頻度の高い3つの単語を表示するプログラムでC++のプログラムをCのプログラムへと書き換えてもらいたいのです。プログラムは、、、

質問の内容が「丸投げ」と取れるのですが…
そのつもりでなくても、質問範囲が広すぎます。

初投稿ということですので、知らなかった、気が付かなかっただけなのかもしれませんが、丸投げそのもの、あるいは丸投げに近い投稿は、どこの掲示板でも嫌われますので注意してください。

丸投げは、いわゆる「Q&A」ではなく、他人の能力によって自分の求める形を得る「委託」です。これは、本来ならば立派にお金になる行為です。
掲示板に投稿したということは、「無償で労力を提供してね」とはっきり言っているようなものですから、いくらボランティアが基本の考え方である掲示板でも、回答する人達はあまり良い顔をしないでしょう。よほどの善人か、時間がたっぷり取れる人でもなければ、普通は答えてくれません。

「ソース全体が理解出来ないためにCへの変換が出来ない」ということであれば、「貴方はまだそのソースを見るだけの能力を身につけていない」「そのソースを参考にするべきではない」ということです。少し厳しい言い方かもしれませんが、このまま作業を続けても途中で絶対に破綻します。
少なくてもCを理解されているのであれば、仕様は分かっているのですから、ご自身で新規にプログラムを作成してしまった方が早く、また確実です。その作成途中で分からないことがあるのならば、その時は掲示板に質問してください。