扫描与筛选

本题目要求编写程序,给出多个非空字符串,再给出一篇文章,统计每个字符串在文章中出现的次数(字母不分大小写)。然后按照字符串的出现次数降序输出,若字符串的出现次数相等,则按照字符串的字典序升序输出。所谓的“字符串”是指连续不含空格的非空字符串。

输入格式:

第一行首先输入一个N(≤10⁴),即字符串的数量,紧接着输入N个字符串,随后每一行输入一串字符。当读到某一行只有一个英文句子.时,输入结束,此行不算在文章内。

输出格式:

如果在文章当中没有出现任何一个给出的字符串输出“No string ever appeared”,否则每一行输出给出的字符串以及它出现的次数。

输入样例:

在这里给出一组输入。例如:

4 A for like look
Can I buy you a drink?
Actually I’d rather have the money.
I’m a photographer. I’ve been look for a face like yours.
I’m a plastic surgeon. I’ve been looking for a face like yours.
.

输出样例:

在这里给出相应的输出。例如:

A 5
for 2
like 2
look 1
//算法标签:双指针 + map
//题解:
//	题意:查询并统计"字符串"的数量,字符串(不含空格的非空字符串)可以由字母、数字、以及
//	      其他可见符号组成(空格除外,其次字母不分大小写,如a和A在统计时可以看作同一个),
//		  然后再按照出现次数降序输出,若出现次数相等按照字符串的字典序升序输出(字符串如:jvb<>{][ui2374&%%**(---+++==~23) 
//	题解:在统计之前把所有的字母换化成小写字母,用map记录转换前和转换后的字符串。
//		  用双指针算法把文章中不含空格的字符串扫描出来,然后再通过substr给截取出来,
//		  截取出来后再判断是否是我们要找的字符串,如果是就用map统计它出现的次数 
#include<bits/stdc++.h>
using namespace std;
typedef pair<string,int> PII; //两个变量,first:字符串 second:出现次数 
bool cmp(PII x, PII y) //排序,若次数不相等按次数降序排序,否则按字典序升序排序 
{
	if(x.second!=y.second) return x.second > y.second;
	else return x.first < y.first;
}
string zhuang( string s ) //把字母全部转换成小写,方便查询字符串 
{
	for(int i=0; s[i]; i++)
		if(s[i]>='A' && s[i]<='Z')
			s[i] = s[i]-'A'+'a';
	return s;
}
map< string, string> id; //两个区域 first: 表示转换后的字符串,second: 表示转换前的字符串 (用作查询和统计字符串) 
map< string, int> q; //两个区域 first: 要统计的字符串,second: 字符串出现的次数 
vector< PII > w; //PII类型,相当于把 字符串 以及 字符串出现的次数 看成一个整体存储在一起,然后进行排序 
string s;
int N, F;
int main()
{
	cin >> N;
	while( N-- ) {
		cin >> s;
		q[s] = 0; //记录字符串,并赋初值为0 
		id[zhuang(s)] = s; //把转换前后的字符串保存下来 
	}
	getchar();
	while(getline(cin,s) && s!=".") {
		s = zhuang( s ); //先把字符串里的字母全转换成小写字母(方便查询) 
		int l = s.size();
		//双指针扫描出不含空格的非空字符串 
		for(int i=0; i<l; i++) {
			// i<l 与 j<l 都是防止 i和j超出范围 
			//absc
			//i   j 
			while(i<l && s[i]==' ') i++; //越过空格使 i 位于字符串的首位置 
			int j = i; //使 j 从字符串的首位置开始扫描字符串 
			while(j<l && s[j]!=' ') j++; //扫描字符串使 j 位于字符串末位置的后一个位置 
			if(i < l ) { //如果还有字符串,就进行截取 
				string r = s.substr( i, j-i); //将扫描出的字符串截取出来
				//id.find(r)!=id.end() 判断这个字符串是不是我们要找的字符串
				//id[[r]第二个区域second代表转换前的字符串,也就是我们要统计的字符串
				//q[ id[r] ] ++ 统计该字符串出现的次数,F = 1 标记出现过我们要找的字符串 
				if(id.find(r)!=id.end()) q[id[r]] ++, F = 1;
			}
			i = j; //跳过该字符串,扫描下一个字符串 
		}
	}
	for(auto i=q.begin(); i!=q.end(); i++) //把字符串以及次数存储到vector< PII > w里 
		w.push_back({i->first,i->second}); //添加 
	sort( w.begin(), w.end(), cmp); //排序 
	for(int i=0; i<w.size()&&F; i++) //如果出现过我们要找的字符串,就输出 
		cout<<w[i].first<<" "<<w[i].second<<endl;
	if(!F) cout<<"No string ever appeared"<<endl; //如果没有出现过要找的字符串,就输出这句话 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_51936803/article/details/124910401