AT—次世代SNS 题解
题外话:这道题原来的题号是
题目传送门
更好的阅读体验?
题意:
给一行一个字符串,其中只包含小写字母,空格和 @,@ 之后接字母的情况才合法,求被 @ 的人的名字。
- 注意:空串不算名字!
思路:
-
-
可以读一个词块就判断一个词块,
cin以空格为界,省去处理空格的麻烦。 -
S.find(ss)是寻找字符串ss 在S 中作为子串出现时第一个字母的位置(从0 开始),若没有返回-1 。 -
S.substr(pos,n)返回的字符串是从pos 起的前n 个字符,注意不要越界。 -
cin读入失败返回0 ,scanf读入失败返回-1 。 -
sort 内部排字符串的方法:
- 先比较首字符的大小(按照
\texttt{ASCII} 码的大小)。- 如果首字母不相等,可以直接按照给定标准排序(就是自己写的函数,默认由小到大)。
- 若相等,则按照
2 的方法继续判断下一个字符,直到有一个字符串的所有字符都判断完了,此时长度短的小于长度长的,按照给定标准排序。
-
AT 的题最后要换行!
-
注意细节。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
string s,ans[101];//ans存被 @ 的人的名字
int tot;//存答案数量
int main()
{
while(cin>>s)//一直读一个单词,可以避免很多麻烦
{
int nw1=s.find('@'),flag=0;
//nw1 是找 '@' 字符的位置
//flag 标记是否搜到最后
while(nw1!=-1)//有 '@'
{
int nw2=s.find('@',nw1+1);
//从 nw1 的下一个字符开始,寻找 '@'
if(nw2==-1)//没有 @' 了
{
nw2=s.size();
//为了使下文的 substr 不用特判
//在全文的末尾再加一个 '@'
//这时 '@' 的位置就是 s.size()
flag=1;//标记已经搜到了最后
}
string wait=s.substr(nw1+1,nw2-(nw1+1));
tot++;
ans[tot]=wait;
//wait 等待判断是否有重复的人名
//先假设没有重复,后面再判断
if(wait.size()==0)
{
//不合法情况之一:
//是空串
tot--;
//不合法,数量减 1
}
for(int i=1;i<=tot-1;i++)
{
if(ans[i]==wait)
{
//不合法情况之二:
//有重复
tot--;
//不合法,数量减 1
break;
//不用继续判断了,跳出循环
}
}
if(flag) break;//搜到末尾了,打破循环
nw1=nw2;
//下一次开始判断的位置
//就是这次判断结束的位置
}
}
sort(ans+1,ans+tot+1);
//sort 默认就是按字典序由小到大排序
for(int i=1;i<=tot;i++)
{
if(ans[i].size()!=0)
{
//如果这个字符串不是空的,就输出
cout<<ans[i]<<endl;
//一行一个名字,AT 的题最后需要换行
}
}
return 0;
}
最快