c++中的一道编程题,统计文章中单词出现的词频并把结果输出到另一个文件中

1.统计一篇英文(The_Holy_Bible.txt)文章中出现的单词和词频。

输入:某篇文章的绝对路径

输出:词典文件dict.txt(词典中的内容为每一行都是一个“单词 词频”)

词典的存储格式如下。

|   a 66          |
|   abandon 77    |
|   public 88     |
|    ...........  |
|_________________|

代码设计:

struct Record
{
	string _word;
	int _frequency;
};

class Dictionary
{
public:
	//......
    void read(const std::string &filename);
    void store(const std::string &filename);
private:
    vector<Record> _dict;
};

提示:因为我们需要统计圣经文件中单词以及该单词在文件中出现的次数,所以可以看去读圣经文件,然后将单词存到数据结构中,并记录单词的次数,如果单词第二次出现的时候,只需要修改单词的次数(也就是这里说的单词的频率),这样当统计完整个圣经文件后,数据都存在数据结构vector了。接着遍历vector数据结构就可以将单词以及单词次数(也就是频率)存储到另外一个文件。(当然如果不存到另外一个文件,就只能打印到终端了)

注意:在读圣经文件的时候,有可能字符串是不合法的,比如:abc123 abc?这样的字符串,处理方式两种:直接不统计这样的字符串或者将非法字母去掉即可。

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
using std::cout;
using std::cerr;
using std::endl;
using std::ifstream;
using std::ofstream;
using std::istringstream;
using std::string;
using std::vector;

struct Record
{
    Record(const string & word,int frequency)
    : _word(word)
    , _frequency(frequency)
    {}

	string _word;
	int _frequency;
};

bool operator<(const Record & lhs,const Record & rhs){
    return lhs._word < rhs._word;
}

class Dictionary
{
public:
    Dictionary(int capacity)
    {
        _dict.reserve(capacity);
    }

    void read(const string &filename){
        ifstream ifs(filename);
        
        if(!ifs){
            cerr << "ifs open file failed!" << endl;
            return;
        }

        //因为磁盘文件读写速度慢,应该尽量减少文件IO的次数
        /* string word; */
        /* while(ifs >> word){ */
        /* } */

        string line;
        while(getline(ifs,line)){
            istringstream iss(line);
            string word;
            while(iss >> word){
                //处理单词
                string newWord = dealWord(word);

                //将单词插入到vector
                insert(newWord);
            }
        }


        //对vector中的元素进行排序
        sort(_dict.begin(),_dict.end());

        ifs.close();
    }

    string dealWord(const string & word){
        for(size_t idx = 0; idx != word.size(); ++idx){
            if(!isalpha(word[idx])){
                return string();//如果有非法字符就返回空字符串
            }
        }
        return word;
    }

    void insert(const string & word){
        if(word == string())
        {
            return;
        }

        //判断这个单词是否已经在vector中了
        size_t idx = 0;
        for(; idx != _dict.size(); ++idx){
            if(word == _dict[idx]._word){
                ++_dict[idx]._frequency;
                break;
            }
        }

        if(idx == _dict.size()){
            _dict.push_back(Record(word,1));
        }
    }


    void store(const string &filename){
        ofstream ofs(filename);
        
        if(!ofs){
            cerr << "ofs open file failed!" << endl;
            return;
        }

        for(size_t idx = 0; idx != _dict.size(); ++idx){
            ofs << _dict[idx]._word << " "
                << _dict[idx]._frequency <<endl;
        }
        ofs.close();
    }
private:
    vector<Record> _dict;
};

void test0(){
    Dictionary dict(10000);
    dict.read("The_Holy_Bible.txt");
    dict.store("dictionary.dat");
}

int main(void){
    test0();
    return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值