zoukankan      html  css  js  c++  java
  • 统计英文文本中的词频

      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来读取,效率很高,用循环读取可能效率很低。

  • 相关阅读:
    H5新增属性02
    h5新增属性
    javascript基础
    多列布局和弹性盒模型详解
    边框图片+盒子倒影
    CSS新增边框属性
    css3选择器
    css3基础
    h5新增-2
    h5新增
  • 原文地址:https://www.cnblogs.com/lovelyxia/p/1916921.html
Copyright © 2011-2022 走看看