注册 登录
编程论坛 C++教室

[求助]如何统计一篇英文文章中每个单词出现的次数

zeno_zheng 发布于 2007-07-02 10:21, 7335 次点击

新手上路,请高手指教: 如何统计一篇英文文章中每个单词出现的次数? 每个单词用空格符或标点分隔,文章可能很长,所以最好兼顾perfermance的问题.

谢谢!

7 回复
#2
百年不亮2007-07-02 11:46
一个字符一个字符的检查,遇到标点记一次数,遇到一个空格后再读到一个非空格也记一次数。
最后读完了看记数的变量就知道了。
#3
zeno_zheng2007-07-02 12:22

to:百年不亮

3Q!
希望我没误会你的意思,但我想要统计每个单词出现的次数,而不是一共有多少个单词.

能不能用哈希表来实现呢,求高手指点迷津,给出基本思想.

#4
天空の城2007-07-02 13:37
#include <map>
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
ifstream* Init(ifstream* ins,map<string,int> &dir)
{
    if(ins->fail())
        return NULL;
    char seps[]=\" ,;.!\'\t\n\\"<>=-+*/%|&^~()[]{}?:@#$\";
    char buf[4096]={0};
    while(ins->getline(buf,4096))
    {
        char *token = strtok(buf, seps );
        while( token != NULL )
        {
            dir[string(token)]++;
            token = strtok( NULL, seps );
        }
        memset(buf,0,4096);
    }
    ins->close();
    return ins;
}
int RepeatTimes(string word,map<string,int> &dir)
{
    return dir[word];
}
void main()
{
    map<string,int> mp;
    ifstream *ins = Init(new ifstream(\"file.dat\"),mp);
    if(ins)
        cout<<RepeatTimes(\"love\",mp)<<endl;
    delete ins;
}

[此贴子已经被作者于2007-7-2 13:39:09编辑过]

#5
zeno_zheng2007-07-02 19:13

谢谢哦,有没有不用STL的解法

#6
aipb20072007-07-02 20:58
回复:(zeno_zheng)谢谢哦,有没有不用STL的解法
不用容器类,那存储单词就比较复杂。

可以用哈希表,不过这里是要统计而不是查询,况且这样的题目应该不会在意效率,用哈希表相对更复杂。
#7
zeno_zheng2007-07-02 23:02
to:aipb2007
谢谢你的解答. 可能是因为跨平台的原因,要求不能使用STL.

说到统计和查询的问题,个人觉得这个问题可能需要做查询的工作.因为要统计出现的每个单词,做个很简单的类作比方
class wordCounterNode
{
public:
...

private:
string word;// 记录文章里每个第一次出现的单词
int totalNum;//记录这个单词出现的次数
};

读到文章后面的单词时,需要和前面已查询过的单词比较,如果通过查询发现在文章前面曾经出现过,直接在相应的计数器上加1,如果没有,得新创建一个wordCounterNode对象,存取这个新出现的单词,并将计数器置1.如果文章中有很多个单词,在查后面的单词时,查询工作会很费时,应该会需要一个快速查询方法。个人认为如果文章中有N个单词,一般查询的算法复杂度是O(n*n),不知道对不,请指教。

这个问题只是我要解决的整个问题中的一个部分,如果太慢,会有perfermance问题。

期待大家给个思路,不胜感激。

#8
aipb20072007-07-03 09:37
to zeno_zeng:

你的思路已经有了,并且很可行,至于跨平台,一样的可以使用stl。
在你的设计思路上,不用标准库容器和算法,当然也可以。

单词的存储,可以用hash table,不过我个人觉得,非海量数据用hash也许不回对效率有很大改善,再有就是你要选择一个合适的hash 函数,让数据最大限度散列,才能有效的实现查询。这应该是个难点。

然后,个人建议:如果文章查询不是太长,比如这个程序只用在控制台里,其实用数组存放分配堆内存也是一种可行的方法。
两种方法你都可以试试,比较下。

遇到什么问题可以一起讨论。
GOOD LUCK
1