当前位置:首页 > 复赛 > 正文内容

NOIP2011年普及组T2 统计单词数

亿万年的星光4年前 (2021-01-28)复赛6535

【题目描述】

一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。

现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同(参见样例1),如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样例2)。

【输入描述】

2 行:

第 1 行为一个字符串,其中只含字母,表示给定单词;

第 2 行为一个字符串,其中只可能包含字母和空格,表示给定的文章。

【输出描述】

只有一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开,分别是单词在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单词首字母在文章中的位置,位置从0 开始);如果单词在文章中没有出现,则直接输出一个整数-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 tim

【输出样例2】

-1

【输入输出样例 1 说明】

输出结果表示给定的单词 To 在文章中出现两次,第一次出现的位置为0。

【输入输出样例 2 说明】

表示给定的单词 to 在文章中没有出现,输出整数-1。

【数据范围】

1 ≤ 单词长度≤ 10。

1 ≤ 文章长度≤ 1,000,000。

【分析】

  1. 题目是字符串处理问题,有一定难度。

  2. 题目忽略大小写,所以要进行统一的大小写转换。

  3. 比较坑的点,输入两行字符,末尾是换行“\n”不处理就会忽略掉第二行的输入。

  4. 比较简单的一点是单词的长度较小。

  5. 注意,空格也算位置。不能忽略空格去查单词的位置。

  6. 当然,字符串有可能出现开头一堆空格,然后再是字符的。这个点更坑。

【思路1】

对于题目中句子和单词来说,匹配的时候遇到空格就可以断定前面的是单词,但是这样,最后一个单词就没法断定,因此可以在单词和句子后面单独加一个空格,这样减少匹配的难度。参考洛谷上一位大神的代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string> 
using namespace std;
int main()
{
	char word[11], sent[1000001]; //定义要读入的单词和句子
	int p=0,flag,sum=0,location; //定义 
	int i,j,k; 
	gets(word);
	gets(sent); //读入单词和句子
	strcat(word," ");
	strcat(sent," ");  //在单词和句子后面加上一个空格,便于匹配。
	strlwr(word);
	strlwr(sent); //统一转换成小写
	
	for(i=0;sent[i]!='\0';i++)  //遍历长的句子, 
	{
		if(sent[i]==' ') //当句子遇到了空格,说明前面的是一个完整的单词 
		{
			flag =1;
			for(j=p, k=0;j<=i,word[k]!='\0'; j++,k++)  //p记录了每个单词的起始位置 
			{
				if(sent[j]==word[k])
					flag*=1; //用flag来记录是否对应,如果每一位都一样,结果就是1
				else
					flag*=0; //一旦有一位不一致就是0  
			}
			if(flag==1)  //符合条件就计数 
				sum++; 
			if(sum==1 && flag ==1)   //记录第一次符合的位置 
				location=p;
			p=i;
			p++; 
		}
	} 
	 
	if(sum==0)
	{	
		sum=-1;
		printf("%d",sum);	
	}else if(sum>0)
	{
		printf("%d %d",sum,location);
	}
			
	return 0;
	
}

【第二种做法,string】

#include <bits/stdc++.h>
using namespace std;
int la,lb,flag,ii,s,q;
string a,b;
int main(){
	//freopen("stat.in","r",stdin);
	//freopen("stat.out","w",stdout);
	getline(cin,a);
	la=a.size(); 
	getline(cin,b);
	lb=b.size(); 
	for(int i=0;i<la;i++){
		if(a[i]>='A'&&a[i]<='Z'){
			a[i]+=32;
		}
	}
	for(int i=0;i<lb;i++){
		if(b[i]>='A'&&b[i]<='Z'){
			b[i]+=32;
		}
	}
	for(int i=0;i<lb;i++){
		flag=1;
		if(b[i]==a[0]){
		    if(i==0){
		        for(int j=i+1;j<la+i;j++){
    				if(b[j]!=a[j-i]){
    					flag=0;
    					break;
    				}
    			}
    			if(flag){
    				cout<<i<<" ";
    				s++;
    				if(ii==-1){
    					ii=i;
    				}
    			}
		    }
			if(b[i-1]>='a'&&b[i-1]<='z'){
				continue;
			}
			for(int j=i+1;j<la+i;j++){
				if(b[j]!=a[j-i]){
					flag=0;
					break;
				}
			}
			if(flag){
				q++;
				if(q==1){
					ii=i;
				} 
				s++;
			}
		}
	}
	if(!s){
		cout<<-1;
		return 0;
	}
	cout<<s<<" "<<ii;
	return 0;
}
/*

*/



扫描二维码推送至手机访问。

版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

分享给朋友:

相关文章

NOIP/CSPJ 复赛中noilinux里的atbiter测评机的使用(附数据)

NOIP/CSPJ 复赛中noilinux里的atbiter测评机的使用(附数据)

0.前言最近这段时间在研究noilinux,NOI考试中的测评系统就在noilinux中,叫做atbiter。自己百度了一下,发现说的都比较官方,自己尝试了一遍,把过程和数据附上,以供参考。1.创建比...

CSPJ2019普及组T1 数字游戏

【题目描述】小 K 同学向小 P 同学发送了一个长度为 8 的 01 字符串来玩数字游戏,小 P 同学想要知道字符串中究竟有多少个 1。注意:01 字符串为每一个字符是 0 或者 1 的字符串,如“1...

NOIP2008年普及组 T2 排座椅

NOIP2008年普及组 T2 排座椅

【问题描述】上课的时候总有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情。不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的D对同学上课时会交头接耳。同学...

NOIP2016年普及组 T2 回文日期

【题目描述】日常生活中,通过年、月、日这三个要素可以表示出一个唯一确定的日期。牛牛习惯用8位数字表示一个日期,其中,前4位代表年份,接下来2位代表月份,最后2位代表日期。显然:一个日期只有一种表示方法...

NOIP2003年普及组 T1 乒乓球

【题目描述】国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及。其中11分制改革引起了很大的争议,有一部分球员因为无法适应新规则只能选择退役。华华就是其中一位,他退...

NOIP2010年普及组T2 接水问题

【题目描述】学校里有一个水房,水房里一共装有m 个龙头可供同学们打开水,每个龙头每秒钟的供水量相等,均为1。现在有n 名同学准备接水,他们的初始接水顺序已经确定。将这些同学按接水顺...