P1308 [NOIP 2011 普及组] 统计单词数
题目描述
一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。
现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同(参见样例 1),如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样例 2)。
输入格式
共222行。
第111行为一个字符串,其中只含字母,表示给定单词;
第222行为一个字符串,其中只可能包含字母和空格,表示给定的文章。
输出格式
一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开,分别是单词在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单词首字母在文章中的位置,位置从000开始);如果单词在文章中没有出现,则直接输出一个整数−1-1−1。
注意:空格占一个字母位。
输入输出样例 #1
输入 #1
To to be or not to be is a question输出 #1
2 0输入输出样例 #2
输入 #2
to Did the Ottoman Empire lose its power at that time输出 #2
-1说明/提示
数据范围
1≤1\leq1≤第一行单词长度≤10\leq10≤10。
1≤1\leq1≤文章长度≤106\leq10^6≤106。
noip2011 普及组第 2 题
解题思路
题目要求输入了一个目标词和一段句子或文章后,输出两个整数,一个代表目标词出现了多少次(不论大小写),另一个代表目标词第一次出现时是在哪里。如果目标词并没有出现过,则只输出一个“-1”。
为了完成题目要求,我们需要实现这些功能:
输入目标词和句子(或文章)
- 注意消除目标词和句子末尾的换行符
- 注意输入句子时需要连空格一起读取
寻找句子的目标词
- 要将目标词和句子统一转换成小写(题目要求不论大小写,那就统一小写吧)
- 注意使用 ASCII 码时不要把标点符号也转换了
- 用空格来区分一个个词语。
- 注意要跳过空格,空格不能算在一个单词内。
输出结果
- 根据不同情况输出不同结果
解
C语言解:
#include<stdio.h>//目标单词(最长10,开15以防万一)charword[15];//句子、文章(最长可能有10的6次方,写大一点防止越界)charsent[1000005];intmain(){//读入第一行的目标单词scanf("%s",word);//吃掉 scanf 留下的换行符,否则会被下面的 fgets 读到getchar();//用 fgets 读入第二行的整篇文章,fgets 可以把空格读进去fgets(sent,sizeof(sent),stdin);//手动计算文章长度(数到 '\0' 为止)intsentlen=0;while(sent[sentlen]!='\0'){sentlen++;}//手动计算目标词长度intwordlen=0;while(word[wordlen]!='\0'){wordlen++;}//去掉文章末尾的换行符,并让长度减1if(sentlen>0&&sent[sentlen-1]=='\n'){sent[sentlen-1]='\0';sentlen--;}//将目标单词统一转成小写(只处理大写字母,避免动到其他字符)for(inti=0;i<wordlen;i++){if('A'<=word[i]&&word[i]<='Z'){word[i]+=32;}}//将文章也统一转成小写,方便后面忽略大小写比较for(inti=0;i<sentlen;i++){if('A'<=sent[i]&&sent[i]<='Z'){sent[i]+=32;}}//count 记录出现次数,firstPos 记录第一次出现的位置(-1表示还没找到)intcount=0;intfirstPos=-1;//开始遍历文章,按下标 i 逐个处理inti=0;while(i<sentlen){//跳过连续空格,空格不属于任何单词while(i<sentlen&&sent[i]==' '){i++;}//如果跳完空格已经到文章末尾,说明没有更多单词了,跳出循环if(i>=sentlen){break;}//记录当前单词的起始位置(也就是题目要的“位置”)intstart=i;//往后找到单词结束(遇到空格或文章末尾)while(i<sentlen&&sent[i]!=' '){i++;}intend=i;//计算当前单词的长度intlenCur=end-start;//只有长度和目标单词相同,才可能匹配if(lenCur==wordlen){intmatch=1;//逐个字符比较(两边都已转小写)for(intj=0;j<wordlen;j++){if(sent[start+j]!=word[j]){match=0;break;}}//如果完全匹配,统计次数并记录第一次出现的位置if(match){count++;if(firstPos==-1){firstPos=start;}}}}//如果一次都没匹配到,输出-1//顺便直接 return 结束程序if(firstPos==-1){printf("-1\n");return0;}//否则输出出现次数和第一次出现的位置printf("%d %d\n",count,firstPos);return0;}另,附上 Java 解:
importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;publicclassMain{publicstaticvoidmain(String[]args){BufferedReaderbufferedReader=newBufferedReader(newInputStreamReader(System.in));Stringword;Stringsentence;try{word=bufferedReader.readLine().toLowerCase();sentence=bufferedReader.readLine().toLowerCase();}catch(IOExceptione){thrownewRuntimeException(e);}intcount=0;intfirstPos=-1;intwordLen=word.length();intsentLen=sentence.length();inti=0;while(i<sentLen){while(i<sentLen&&sentence.charAt(i)==' '){i++;}if(i>=sentLen)break;intstart=i;while(i<sentLen&&sentence.charAt(i)!=' '){i++;}intend=i;if(end-start==wordLen){booleanmatch=true;for(intj=0;j<wordLen;j++){if(word.charAt(j)!=sentence.charAt(start+j)){match=false;break;}}if(match){count++;if(firstPos==-1){firstPos=start;}}}}if(firstPos==-1){System.out.println("-1");return;}System.out.println(count+" "+firstPos);}}