从文件中查找出现次数最多的10个单词

本来想用字典树的,但字典树是空间换时间的,只有26个字母还好,但文件中还有各种标点符号,觉得空间耗费太大了。。。。就用了还算一般的方法。。


十道海量数据处理:http://blog.csdn.net/v_july_v/article/details/6279498

字典树参考:http://www.cnblogs.com/DiaoCow/archive/2010/04/19/1715337.html  && http://blog.csdn.net/bill_ming/article/details/7585009


附代码:见注释(VS2008)

//假设数据能一次全装入内存

#include <iostream>
#include <algorithm>
#include <fstream>
#include <map>
#include <vector>
#include <iterator>
#include <functional>
#include <string>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <cstdlib>
using namespace std;
#define SEARCH_COUNT 10  //打印前多少个单词
//单词类
class WordTop10
{
private :
    map<string,int> mapWord;   //存储单词
   vector<pair<string ,int > > pair_vec;  //因为要按map的value排序,借助vector
public :

    void insertWord(const string& word);  //插入单词到map
    void sortWord();                                  //按map的value排序
    void readFile(const string& strFileName); //从文件读数据
    void outPut();                                          //输出
};

//在map中插入一个单词
void WordTop10::insertWord(const string& word)
{
    map<string,int>::iterator mit;
    mit = mapWord.find(word);
    if( mit != mapWord.end())
    {
        mit->second ++;
    }
    else
    {
        mapWord[word] = 1;
    }
}
//递减排序
int cmp(const pair<string ,int >& a,const pair<string ,int >& b)
{
    return a.second > b.second;
}
//按map中的value排序
void WordTop10::sortWord()
{
   
    for(map<string,int>::iterator map_iter = mapWord.begin(); map_iter != mapWord.end(); ++map_iter)
    {
        pair_vec.push_back(make_pair(map_iter->first,map_iter->second));
    }
    sort(pair_vec.begin(),pair_vec.end(),cmp);   //排序
   
}

void WordTop10:: outPut()
{
    int i = 0;
    for(vector<pair<string ,int > >::iterator cur = pair_vec.begin(); cur != pair_vec.end(); ++cur)
    {
        i++;
        if(i >SEARCH_COUNT)   //输出前SEARCH_COUNT个
        {
            return ;
        }
        cout << cur->first <<"\t"<<cur->second<<endl;
    }
}


//从文件中读取数据
void WordTop10::readFile(const string& strFileName)
{
    string text;
// c_str函数的返回值是const char*的,不能直接赋值给char*,所以就需要我们进行相应的操作转化,下面就是这一转化过程。
	ifstream in(strFileName.c_str());

    if (!in)
    {
        cout << "~文件打开失败~" << endl;

    }

    while (in >> text)
    {
        //text.erase(remove_if(text.begin(),text.end(),bind2nd(equal_to<char>(),'-')), text.end());

        //因为读入是以空格分割的,需要处理两边的表标点符号
        //取出最后的标点,假设最多有三个尾标点
        string::iterator it = text.end();
        if(text.length() != 0 &&  ispunct(text[text.length()-1]))   //如果最后那个是标点     /* 注意判断长度啊啊啊啊啊,否则string subscript out of range*/
            text.erase(it-1);                  //去掉最后那个标点

        it = text.end();  
         if(text.length() != 0 && ispunct(text[text.length()-1]))
            text.erase(it-1);

		  it = text.end();  
         if(text.length() != 0 &&  ispunct(text[text.length()-1]))
            text.erase(it-1);
        //有时前面也有符号 ,假设3个
        it = text.begin();
       if(text.length() != 0 &&ispunct(text[0]))
            text.erase(it);

        it = text.begin(); 
       if(text.length() != 0 && ispunct(text[0]))
            text.erase(it);

		     it = text.begin();
       if(text.length() != 0 &&ispunct(text[0]))
            text.erase(it);

        //很多字符串带 “--”,特殊处理,--也是标点符号,两头的已在前面处理过,这里处理中间的
        size_t npos = text.find("--");
        if( npos != -1)
        {
            string text1 = text.substr(0,npos);  //--把text分割成两个单词
			string text2 = text.substr(npos+2);
            insertWord(text1);
            insertWord(text2);

        }
        else
        {
            insertWord(text);
        }
		
    }

    in.close();
    in.clear();
    return ;
}

//文件属性要是ANSI,而且不能有汉字  。将项目设置中->配置属性->C/C++->语言->默认Char无符号,选择是(/J)即可解决
//参考:http://blog.csdn.net/bill_ming/article/details/8191551
int main()
{
    string fileName = "haha.txt";
    WordTop10 wordTop;

    wordTop.readFile(fileName);
	clock_t start = clock();
    wordTop.sortWord();
	clock_t finish = clock();
	double duration = (double)(finish - start) / CLOCKS_PER_SEC;
	cout << "排序时间" << duration<<endl;
	 wordTop.outPut();
    return 0;
}



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值