zl程序教程

您现在的位置是:首页 >  其它

当前栏目

词频字典

字典 词频
2023-09-11 14:20:39 时间


现在要统计《圣经》英文版《Bible》中的所有单词出现的次数。再输出出现频率最高的10个单词。


一、没有实现去数字和符号

//没有实现去数字和符号

//#include <bits/stdc++.h> //C++万能头文件 
#include <iostream>
#include <string>
#include <fstream>
#include <map>    //用map实现自动排序功能(TreeMap,按升序排列,用红黑树实现)
#include <vector>

//using namespace std;
using std::cout;
using std::endl;
using std::string;
using std::ifstream;
using std::ofstream;
using std::map;
using std::vector;
using std::pair;

class Dictionary
{
public:
    void read(const std::string &filename);//成员函数read的声明
    void store(const std::string &filename);//成员函数store的声明
private:
    map<string,int>_dict;//map创建对象_dict:map键值对,以string存储 词汇 ,以int存储 词频
};//字典类结束,以分号;结束。(除了头文件和函数,都以分号;结尾。)


void Dictionary::read(const string &filename)//类Dictionary的成员函数read的实现,函数必须有函数体{}
{                                           //作用:读取filename文件
                                            //&failename是引用,相当于输入了文件名
    ifstream ifs(filename);//读取文件,已经被引用过,所以这里filename是形参
    if (!ifs.good())  //通过流的状态判断是否正确打开了目标文件
    {
        cout << "文件打开失败:ifs open Error!" << endl;
    }
    string word;//一个单词一个单词读取
    cout << "开始读取圣经内容..." << endl;
    while (ifs.good()) //如果没有到文章末尾,则循环读取,直至文件指针指到文章末尾
    {
        ifs >> word;       //string按照空格来区分是几个字符串,没空格自然当成一个字符串
        _dict[word]++;     //map具有下标访问功能,若map中已有该string,则词频+1,若没有则保存
    }
    cout << "读取完毕。" <<endl;
    ifs.close();    //文件输入流关闭
}

void Dictionary::store(const string &filename)//成员函数store
{
    ofstream ofs(filename);
    vector<pair<string,int>> vec(_dict.begin(),_dict.end());//vector创建对象vec:    vector<int> vec;
    cout <<"开始输出词频字典..."<< endl;
    for(vector<pair<string,int>>::iterator it = vec.begin();it<vec.end();it++)   //利用动态数组vector里
    {
    string key = it->first;   //first是map< , >的第一个值
    int value = it->second;   //second是map< , >的第二个值
    ofs << key << " 出现的次数为: " << value << endl;
    }
    cout << "输出词频字典文件:dictionaty.txt完毕。" << endl;
    ofs.close();     //文件输出流关闭
} 


int main()
{
    Dictionary dict;//类Dictionary创建一个对象dict
    dict.read("The_Holy_Bible.txt");//以“对象.函数”的形式,让dict调用成员函数read
    dict.store("dictionary.txt");//对象dict调用成员函数store
    return 0;
}



二、实现去数字和符号,仅统计频率

//#include <bits/stdc++.h> //C++万能头文件 
#include <iostream>
#include <string>
#include <fstream>
#include <map>    //用map实现自动排序功能(TreeMap,按升序排列,用红黑树实现)
#include <vector>

//using namespace std;
using std::cout;
using std::endl;
using std::string;
using std::ifstream;
using std::ofstream;
using std::map;
using std::vector;
using std::pair;

class Dictionary
{
public:
    void read(const std::string &filename);//成员函数read的声明
    void store(const std::string &filename);//成员函数store的声明
private:
    map<string,int>_dict;//map创建对象_dict:map键值对,以string存储 词汇 ,以int存储 词频
};//字典类结束,以分号;结束。(除了头文件和函数,都以分号;结尾。)


void Dictionary::read(const string &filename)//类Dictionary的成员函数read的实现,函数必须有函数体{}
{                                           //作用:读取filename文件
                                            //&failename是引用,相当于输入了文件名
    ifstream ifs(filename);//读取文件,已经被引用过,所以这里filename是形参
    if (!ifs.good())  //通过流的状态判断是否正确打开了目标文件
    {
        cout << "文件打开失败:ifs open Error!" << endl;
    }
    string word;//一个单词一个单词读取
    cout << "开始读取圣经内容..." << endl;
    while (ifs.good()) //如果没有到文章末尾,则循环读取,直至文件指针指到文章末尾
    {       
        ifs >> word;       //string按照空格来区分是几个字符串,没空格自然当成一个字符串
        int len = word.length();
        bool flag = true;
        for(int i=0;i<len;i++)
        {
            if(word.empty())
            {
                flag=false;
                break;
            }
            else
            {
                if( (word[i]<'A') || ((word[i]>'Z')&&(word[i]<'a')) || (word[i]>'z') )   
                {   
                    flag=false;
                    break;
                }
            }
        }
        if(flag)
            _dict[word]++;     //map具有下标访问功能,若map中已有该string,则词频+1,若没有则保存
    }
    cout << "读取完毕。" <<endl;
    ifs.close();    //文件输入流关闭
}

void Dictionary::store(const string &filename)//成员函数store
{
    ofstream ofs(filename);
    vector<pair<string,int>> vec(_dict.begin(),_dict.end());//vector创建对象vec:    vector<int> vec;
    cout <<"开始输出词频字典..."<< endl;
    for(vector<pair<string,int>>::iterator it = vec.begin();it<vec.end();it++)   //利用动态数组vector里
    {
    string key = it->first;   //first是map< , >的第一个值
    int value = it->second;   //second是map< , >的第二个值
    ofs << key << " 出现的次数为: " << value << endl;
    }
    cout << "输出词频字典文件:dictionaty.txt完毕。" << endl;
    ofs.close();     //文件输出流关闭
} 


int main()
{
    Dictionary dict;//类Dictionary创建一个对象dict
    dict.read("The_Holy_Bible.txt");//以“对象.函数”的形式,让dict调用成员函数read
    dict.store("dictionary.txt");//对象dict调用成员函数store
    return 0;
}



三、选出频率最高的10个单词

将map按pair<string int>存入vector中,再用sort进行排序

//#include <bits/stdc++.h> //C++万能头文件 
#include <iostream>
#include <string>
#include <fstream>
#include <map>    //用map实现自动排序功能(TreeMap,按升序排列,用红黑树实现)
#include <vector>
#include <algorithm>

//using namespace std;
using std::cout;
using std::endl;
using std::string;
using std::ifstream;
using std::ofstream;
using std::map;
using std::vector;
using std::pair;

class Dictionary
{
public:
    void read(const std::string &filename);//成员函数read的声明
    void store(const std::string &filename);//成员函数store的声明
    void sort(const std::string &filename);
private:
    map<string,int>_dict;//map创建对象_dict:map键值对,以string存储 词汇 ,以int存储 词频
    //map<int,string>fre;
};


void Dictionary::read(const string &filename)//类Dictionary的成员函数read的实现,函数必须有函数体{}
{                                           //作用:读取filename文件
                                            //&failename是引用,相当于输入了文件名
    ifstream ifs(filename);//读取文件,已经被引用过,所以这里filename是形参
    if (!ifs.good())  //通过流的状态判断是否正确打开了目标文件
    {
        cout << "文件打开失败:ifs open Error!" << endl;
    }
    string word;//一个单词一个单词读取
    cout << "开始读取圣经内容..." << endl;
    while (ifs.good()) //如果没有到文章末尾,则循环读取,直至文件指针指到文章末尾
    {       
        ifs >> word;       //string按照空格来区分是几个字符串,没空格自然当成一个字符串
        int len = word.length();
        bool flag = true;
        for(int i=0;i<len;i++)
        {
            if(word.empty())
            {
                flag=false;
                break;
            }
            else
            {
                if( (word[i]<'A') || ((word[i]>'Z')&&(word[i]<'a')) || (word[i]>'z') )   
                {   
                    flag=false;
                    break;
                }
            }
        }
        if(flag)
            _dict[word]++;     //map具有下标访问功能,若map中已有该string,则词频+1,若没有则保存
    }
    cout << "读取完毕。" <<endl;
    ifs.close();    //文件输入流关闭
}

void Dictionary::store(const string &filename)//成员函数store
{
    ofstream ofs(filename);
    vector<pair<string,int>> vec(_dict.begin(),_dict.end());//将map存入vector
    //vector<pair<string,int>> vec;
    //for(auto it =_dict.begin();it !=_dict.end();it++)
    //    vec.push_back(make_pair(it->first,it->second));
    std::sort(vec.begin(),vec.end(),
              [](const pair<string,int> &x,const pair<string,int> &y)-> int{return x.second > y.second;}
              );//按照value排序
    cout <<"开始输出词频字典..."<< endl;
    //for(vector<pair<string,int>>::iterator it=vec.begin();it<vec.end();it++)   //利用动态数组vector里
    for(vector<pair<string,int>>::iterator it=vec.begin();it<vec.begin()+10;it++)  
    {
        string key = it->first;   //first是map< , >的第一个值
        int value = it->second;   //second是map< , >的第二个值
        ofs << key << " 出现的次数为: " << value << endl;
    }
    cout << "输出词频字典文件:dictionaty.txt完毕。" << endl;
    ofs.close();     //文件输出流关闭
} 


int main()
{
    Dictionary dict;//类Dictionary创建一个对象dict
    dict.read("The_Holy_Bible.txt");//以“对象.函数”的形式,让dict调用成员函数read
    dict.store("dictionary.txt");//对象dict调用成员函数store
    return 0;
}