STL 读取TXT文件中单词并按出现次数排序

本文介绍如何使用STL从TXT文件读取英文文章,统计单词出现频率,并按次数排序输出前30个单词。涉及string、map、vector等容器运用。

STL 读取TXT文件中单词并按出现次数排序

要求:从一个文件中读入一篇英文文章,假设该英文文章中只有空格与回车作为分隔符,没有其他标点符号。将这篇英文文章中的英文单词按出现的次数排序(大小写同时出现的,统一转为小写),并将出现次数最多的前30个单词及出现的次数输出。

读取TXT文件

将文件流的内容读到string字符串中

按行读取:

string data;

while (getline(ss, data))

{

    //一行数据会读入到data中,循环处理每一行

}

分割字符串

将字符串分割,可以使用find函数。

定义一个当前位置,然后查找到空格所在的位置,将当前位置和空格所在的位置之间的字符放入一个新的string中,记得,更新当前位置。

如  abc def字符串,当前位置为0,find寻找空格会返回指向位置3的迭代器,

it-data.begin()可以得到3这个数值,将0-3之间的内容放入到新的string中即可。

转换

为方便排序,将所有单词变成小写单词,通过使用函数transform

排序

将所有单词按照出现的次数排序,需要借助vector容器完成,将整个map的所有内容拷贝到一个vector容器中,借助于sort函数来实现。注意,需要写一个“谓词”用于排序。

代码如下

#include <iostream>
#include<fstream>
#include<string>
#include<sstream>
#include<vector>
#include<algorithm>
#include<map>

using namespace std;

int cmp(const pair<string, int>& a, const pair<string, int>& b)
{
    return a.second > b.second;
}

int main()
{
	ifstream t("C:\\Users\\X-Ray\\Desktop\\novel.txt");
	stringstream buffer;
	buffer << t.rdbuf();
	string in(buffer.str());
	t.close();

    int k = 0;
    string str;
    string data;
	string::iterator it;

    map<string, int> *words = new map<string, int>;
	while (getline(buffer, data)) {
		int i = 0;
		int j = 0;
		it = data.begin();
		if (find(it, data.end(), ' ') == data.end()) {

			string s = data.substr(0, data.end() - data.begin());
			transform(s.begin(), s.end(), s.begin(), (int (*)(int))tolower);
			map<string, int>::iterator Find = words->find(s);

			if (Find == words->end()) {
				words->insert(pair<string, int>(s, 1));
			}
			else {
				(Find->second)++;
			}
		}


		else if (*data.begin() == ' ') {
			while (it != data.end()) {
				i = it - data.begin();
				it++;

				if (it != data.end() && *it != ' ') {

					j = find(it, data.end(), ' ') - data.begin();
					string s = data.substr(i + 1, j - i);
					transform(s.begin(), s.end(), s.begin(), (int (*)(int))tolower);
					map<string, int>::iterator Find = words->find(s);
					if (Find == words->end()) {
						words->insert(pair<string, int>(s, 1));
					}
					else {
						(Find->second)++;
					}
				}
				it = find(it, data.end(), ' ');
			}
		}

		else {
			i = it - data.begin();
			it = find(data.begin(), data.end(), ' ');
			j = it - data.begin();
			string s = data.substr(i, j - i);
			transform(s.begin(), s.end(), s.begin(), (int (*)(int))tolower);
			map<string, int>::iterator Find = words->find(s);
			if (Find == words->end()) {
				words->insert(pair<string, int>(s, 1));
			}
			else {
				(Find->second)++;
			}
			while (it != data.end()) {
				i = it - data.begin();
				it++;
				if (it != data.end() && *it != ' ') {

					j = find(it, data.end(), ' ') - data.begin();
					string s = data.substr(i + 1, j - i);
					transform(s.begin(), s.end(), s.begin(), (int (*)(int))tolower);
					map<string, int>::iterator Find = words->find(s);
					if (Find == words->end()) {
						words->insert(pair<string, int>(s, 1));
					}
					else {
						(Find->second)++;
					}
				}
				it = find(it, data.end(), ' ');
			}
		}
	}

	vector<pair<string, int> > v;
	map<string, int>::iterator i;
	for (i = words->begin(); i != words->end(); i++)    //copy
		v.push_back(*i);
	delete words;
    sort(v.begin(), v.end(), cmp);

	for (int m = 0; m < 30; m++) {
        cout << v[m].first << '\t' << v[m].second << endl;
    }
    
    return 0;
} 

运行效果

TXT文件链接:https://pan.baidu.com/s/1L9yrDquIdIU5Ur5VMVSJ6w 
提取码:43u3

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PlanetRT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值