小H的问题 | ||||||
|
||||||
Description | ||||||
小H是一个可爱的女孩,她特别喜欢看推特(tweeter)。有一天她得到了某位用户的一些推特消息,想从中提取出这个用户在这些消息中@了哪些人。但是这些消息太长了,她想请你来帮她完成这个任务。 每条消息中只会包含ASCII编码中的可见字符与空格。 推特中用户名的定义为一个长度大于0的字符串,且字符串中只包括数字0-9,英文字符a-z与A-Z,’-’与’_’。用户名区分大小写。 对@一个人的判定方式为:在消息中出现了”@username”,其中username为一个用户名,且为’@’后面所能匹配到最长的用户名。如”@TOM”,只能得到用户名TOM而不能得到用户名TO。同时’@’前面不能是一个合法的用户名字符,我们以此排除所有的邮箱信息。如”[email protected]”我们不会提取出用户名,但”[email protected]”我们要从中提取出”qq”。 |
||||||
Input | ||||||
输入数据第一行为T,代表数据组数。(T<=5) 对于每组数据,第一行为n,代表推特消息数。接下来的n行中,每一行有一条长度小于140的推特消息。(n<=5) |
||||||
Output | ||||||
对于每组数据,第一行为k,代表n条消息中共@了多少个人(若同一个人被@了不止一次,则我们只记录一次)。接下来的k行中,每一行输出一个被@的用户名,k个用户名按照字典序排序。 |
||||||
Sample Input | ||||||
2 5 @all, wish you have a nice contest~~~ Good Luck with you, @Contestant, @HUST! Have Fun! :-) @All Competition Topics By @HIT-CCPC All Copyright Reserved @CCPC2018, @HIT-CCPC 4 HIT@CCPC @HUST @HIT-CCPC @CCPC2018 |
||||||
Sample Output | ||||||
6 All CCPC2018 Contestant HIT-CCPC HUST all 3 CCPC2018 HIT-CCPC HUST |
思路:
简单但又非常坑的模拟题,用户名满足的条件有:@之前的字符必须是不合法的,@之后的一直到不合法字符是用户名。
由于要判断@的前一个字符是否合法,所以当@出现在第一个时要单独判断,这时候要注意的是连续@的情况,即@@@123
代码:
#include <cstdio> #include <iostream> #include <string> #include <set> using namespace std; bool isRight(char ch) { if((ch>='a'&&ch<='z') || (ch>='A'&&ch<='Z') || (ch>='0'&&ch<='9') || ch == '-' || ch == '_') return true; return false; } set<string>myset; set<string>::iterator it; int main() { int t, n; cin >> t; while(t --){ myset.clear(); cin >> n; getchar(); for(int i=0; i<n; i++){ string str, temp; getline(cin, str); for(int j=0; j<str.size(); j++){ if(j==0 && str[j]=='@'){ ///单独判断当@在第一位时 int k = 1; while(isRight(str[k])) temp += str[k++]; if(!temp.empty()) ///要判断是否为空,否则在输出时会输出空字符 myset.insert(temp); temp.clear(); } if(str[j] == '@' && !isRight(str[j-1]) && j!=str.size()-1 && j!=0){ int k = j+1; while(isRight(str[k])) temp += str[k++]; if(!temp.empty()) myset.insert(temp); temp.clear(); } } } cout << myset.size() << endl; for(it=myset.begin(); it!=myset.end(); it++){ cout << *it << endl; } } }