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;
}