统计英文文本中的词频

  NLP的文本分类过程中,大多会统计文章的词频,这是分类的重要依据之一。词频是由一个pair组成的,word是key

frequece是value。用什么方法统计最好,当然是map。用vector,list也可以实现,但是它们基于关键字的检索效率没有

map高,map一般是用rb-Tree实现的,查找效率是O(log(n)),list,vector都是线性的,查找复杂度是O(n)。

  先上代码。

header
#ifndef _WORD_FREQUENCE_
#define _WORD_FREQUENCE_
#include
<map>
#include
<iostream>
#include
<string>
using std::map;
class WordFrequence{
public:
WordFrequence(): file_name_(NULL){}
WordFrequence(
char *file_name): file_name_(file_name){
LoadFromFile();
ReplaceSymbol();
parse();
}
private:
char *file_name_;
char *text;
map
<std::string, int> word_frequence_map_;
void parse();
void ReplaceSymbol();
void LoadFromFile();
bool IsWhiteChar(const char chr);
friend std::ostream
& operator<<(std::ostream& os, const WordFrequence& wf);
};
#endif
cpp
#include "word_frequence.h"
#include
<string>
#include
<iostream>
#include
<fstream>
#include
<map>

const char *symbols = "~!@#$%^&*()_+-=[]\\{}|:\";',./<>?";
const int MAX_SIZE = 100000;

bool WordFrequence::IsWhiteChar(const char chr){
switch (chr){
case '\t':
case '\r':
case '\n':
case ' ':
case '\0':
return true;
default:
return false;
}
}

void WordFrequence::LoadFromFile(){
std::ifstream
is(file_name_, std::fstream::in);
if(!is)
std::cerr
<<"error: can't open file: "<<"["<<file_name_<<"]"<<std::endl;
text
= new char[MAX_SIZE];
is.read(text, MAX_SIZE);
}

void WordFrequence::parse(){
word_frequence_map_.clear();
int index=0;
int count = strlen(text);
std::
string str;
while(index < count){
for(int i=index; i<=count; ++i){
if(IsWhiteChar(text[i])){
int len=i-index + 1;
char *p = new char[len];
memcpy(p, text
+index, i-index);
p[len
-1] = '\0';
str
=p;
++word_frequence_map_[str];
index
= i+1;
while(IsWhiteChar(text[index]))
++index;
break;
}
}
}
}

void WordFrequence::ReplaceSymbol(){
int j=0;
while(*(text+j) != '\0'){
for(int i=0; i<strlen(symbols); ++i){
if(*(text+j)==symbols[i])
*(text+j)=' ';
}
j
++;
}
}

std::ostream
& operator<<(std::ostream& os, const WordFrequence& wf){
os
<<"word\t\tfrequence"<<std::endl;
os
<<"-----------------------"<<std::endl;
std::map
<std::string, int>::const_iterator i_begin = wf.word_frequence_map_.begin();
std::map
<std::string, int>::const_iterator i_end = wf.word_frequence_map_.end();
while(i_begin != i_end){
os
<<""<<i_begin->first<<"\t\t"<<i_begin->second<<""<<std::endl;
++i_begin;
}
return os;
}
#include <iostream>
#include
"word_frequence.h"
using namespace std;

int main(int argc, char* argv[])
{
WordFrequence wf(
"d:\\test.txt");
return 0;
}

  实现的方式很简单,首先把从文件里load出text,然后去掉里面的符号,最后扫描一遍文件,遇着单词就塞到map

里面.

++word_freq_map["word"];

这句话太好用了。一句话实现插入map,如果有就增加value,如果没有就插入。

  这个程序简单训练了一下map容器的使用方法,也用到文件的读取。注意ostream open以后一定要判断open

成功了没有。ostream有几种读取方式,有格式化的>>读取,也有getline这种一行读取的,也有getchar这种一个字符

读一次的。也有read这种一次读一大段二进制的。读的时候一定要对文件内容有先验知识。

  如果一次读的数据量很大,建议read来读取,效率很高,用循环读取可能效率很低。

原文地址:https://www.cnblogs.com/lovelyxia/p/1916921.html