统计单词数
题目描述
一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。
现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同(参见样例1 ),如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样例2 )。
输入格式
共22行。
第11行为一个字符串,其中只含字母,表示给定单词;
第22行为一个字符串,其中只可能包含字母和空格,表示给定的文章。
输出格式
一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开,分别是单词在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单词首字母在文章中的位置,位置从00 开始);如果单词在文章中没有出现,则直接输出一个整数-1−1。
输入输出样例
输入 #1
To
to be or not to be is a question
输出 #1
2 0
输入 #2
to
Did the Ottoman Empire lose its power at that time
输出 #2
-1
说明/提示
数据范围:
1≤1≤单词长度≤10≤10。
1≤1≤文章长度≤1,000,000≤1,000,000。
noip2011普及组第2题,洛谷新手村。
本题思路:
本来打算使用scanf(“%s”)来实现一个接着一个的单词输入,并strcmp判断。
#include<bits/stdc++.h> using namespace std; int main() { char s[20]; char p[20]; char t[20]; char x; int cnt=0; scanf("%s",s); strcpy(p,s); if(s[0]>='A'&&s[0]<='Z') p[0]=s[0]+32; if(s[0]>='a'&&s[0]<='z') p[0]=s[0]-32; int i=0; int index=0; scanf("%s",t); x=getchar(); while(x!='\n'){ if(strcmp(t,s)||strcmp(t,p)){ if(cnt==0) index=i; cnt++; }i++; scanf("%s",t); x=getchar(); } if(cnt==0)printf("-1"); else printf("%d %d",cnt,index); return 0; }
但是经过测试发现,%s后并不会将此单词的下一个单词计入,而是跳转到下一行,继续。与题意不符。而且单词的长度不确定。所以转变思路使用getchar一个一个判断。
最后采用以下思路:
#include<bits/stdc++.h> using namespace std; string sent,word; int lens,lenw,t,pos; int main() { getline(cin,word); getline(cin,sent); //字符串含有空格输入,不可以用cin,否则to me只能读到to lenw=word.size(); lens=sent.size(); int j; for(int i=0;i<lenw;i++) word[i]=toupper(word[i]); //转成大写 for(int i=0;i<lens;i++) sent[i]=toupper(sent[i]); t=0; for(int i=0;i<=lens-lenw;i++){ for( j=0;j<lenw;j++){ if(sent[i+j]!=word[j])break; if(i>0&&sent[i-1]!=' ')break; }//用于判断是否为逐字符合。 if(j==lenw&&(sent[i+j]==' '||i+j==lens)) //判断条件是否符合 { t++; if(t==1)pos = i; } } if(t==0)cout<<-1; else cout<<t<<" "<<pos; return 0; }
上述答案的作者为: Zehra
以上即为解答,其中在寻找解题方案的过程中,我还发现许多大佬的许多种方案:比如状态机,根据不同的状态跑程序,但是略微有些麻烦,于是决定使用以上的方案。