Scan and filter

This topic requires writing a program, given multiple non-empty strings, and then given an article, counting the number of times each string appears in the article (letters are not case-sensitive). Then output in descending order according to the number of occurrences of the strings, if the number of occurrences of the strings is equal, output in ascending order according to the lexicographical order of the strings. The so-called "string" refers to a continuous non-empty string without spaces.

Input format:

The first line first enters an N (≤10⁴), which is the number of strings, followed by N strings, and then a string of characters in each line. When a certain line has only one English sentence, the input ends, and this line is not included in the article.

Output format:

If none of the given strings appears in the article, output "No string ever appeared", otherwise each line outputs the given string and the number of times it appears.

Input sample:

A set of inputs is given here. For example:

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.
.

Sample output:

The corresponding output is given here. For example:

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;
}

 

Guess you like

Origin blog.csdn.net/qq_51936803/article/details/124910401