描述:
我们大家经常用google检索信息,但是检索信息的程序是很困难编写的;现在请你编写一个简单的全文检索程序。问题的描述是这样的:给定一个信息流文件,信息完全有数字组成,数字个数不超过60000个,但也不少于60个;再给定一个关键字集合,其中关键字个数不超过10000个,每个关键字的信息数字不超过60个,但也不少于5个;两个不同的关键字的前4个数字是不相同的;由于流文件太长,已经把它分成多行;请你编写一个程序检索出有那些关键字在文件中出现过。
第一行是两个整数M,N;M表示数字信息的行数,N表示关键字的个数;接着是M行信息数字,然后是一个空行;再接着是N行关键字;每个关键字的形式是:[Key No. 1] 84336606737854833158。
输出只有一行,如果检索到有关键字出现,则依次输出,但不能重复,中间有空格,形式如:Found key: [Key No. 9] [Key No. 5];如果没找到,则输出形如:No key can be found !
初读此题,马上想到C里的strstr()函数,完整匹配,很快代码出来了
V1.0
#include<stdio.h>
#include<string.h>
#define max 60001
char list[max];
int main()
{
char * tp;
int n=0,m=0;
while(EOF!=scanf("%d %d",&n,&m))
{
tp=list;
int i,count=0;
scanf("%s",tp);
while(*tp!='/0')
{
tp++;
count++;
}
for(i=1;i<n;i++)
{
scanf("%s",tp);
if(i==n)
break;
tp+=count;
}
char x=getchar();
int NO,j=0;
int all[10001];
while(m--)
{
x=getchar();
char temp[100];
tp=temp;
scanf("[Key No. %d] %s",&NO,tp);
if(strstr(&list[0],tp)!=NULL)
{
all[j]=NO;
j++;
}
}
int flag=0;
if(j==0)
{
printf("No key can be found !/n");
continue;
}
while(j--)
{
if(flag==0 && list[j]!=0)
{
printf("Found key: [Key No. %d]",all[j]);
flag=1;
}
else
{
printf(" [Key No. %d]",all[j]);
}
}
printf("/n");
}
return 0;
}
提交发现T了,重读此题,发现T的原因可能是strstr函数效率比较低,遂自己重写一个类似strstr()的匹配函数find()
函数初步设计为DP思想,完成代码如下:
V2.0
#include<stdio.h>
#define max 60001
char list[max];
int find(char *fl)
{
int temp[max];
int path[max];
int j=0;
int i=0;
while(list !='/0')
{
if(list==*fl)
{
temp[j]=i;
j++;
}
i++;
}
fl++;
while(*fl!='/0')
{
i=0;
while(j--)
{
if(list[temp[j]+1]==*fl && temp[j]+1<max)
{
path=temp[j]+1;
i++;
}
}
if(i==0)
return -1;
j=i;
while(i--)
{
temp=path;
}
fl++;
}
return 1;
}
int main()
{
char * tp;
int n=0,m=0;
while(EOF!=scanf("%d %d",&n,&m))
{
tp=list;
int i,count=0;
scanf("%s",tp);
while(*tp!='/0')
{
tp++;
count++;
}
for(i=1;i<n;i++)
{
scanf("%s",tp);
if(i==n)
break;
tp+=count;
}
char x=getchar();
int NO,j=0;
int all[10001];
while(m--)
{
x=getchar();
char temp[100];
tp=temp;
scanf("[Key No. %d] %s",&NO,tp);
if(find(tp)!=-1)
{
all[j]=NO;
j++;
}
}
int flag=0;
if(j==0)
{
printf("No key can be found !/n");
continue;
}
while(j--)
{
if(flag==0 && list[j]!=0)
{
printf("Found key: [Key No. %d]",all[j]);
flag=1;
}
else
{
printf(" [Key No. %d]",all[j]);
}
}
printf("/n");
}
return 0;
}
再次提交,发现还是T了,重新读题,还是没明白什么个情况....
最后翻阅前人代码,最后终于发现了问题所在还有题目的具体意思:
程序问题分析:
V1.0在于strstr效率的确是太低
V2.0的DP没有必要,一个是收敛慢,还有一个题目要求输出是否出现而不是出现几次..- -!
题目要求分析:
一.输入流文件信息全为数字
二.两个不同的关键字的前4个数字是不相同的
三.输出出现关键字的标号
可设计程序如下:
取每个关键字前4个数字组成一个4位数存10000长度的数组tp[],匹配流文件的时候每次取4个也组成一个四位数进行匹配,匹配判断即tp【此4位数】是否被标记过,标记过则匹配整个key,仍然全部匹配即可判断匹配存结果数组即可
同理整个流文件一次循环结束即可判断所有key是否匹配。
部分程序如下:
int findall()
{
int i=0,j=0;
int cuo= (list[0]-48)*100 + (list[1]-48)*10 + list[2]-48;
while(list!='/0')
{
cuo=(cuo%1000)*10 + list-48;
if(tpp[cuo] != 0)
{
lenth=i+4;
if( check(chen[tpp[cuo]]) == 1)
{
all[j]=tpp[cuo];
tpp[cuo]=0;
j++;
}
}
i++;
}
return j;
}
程序最终完成,提交AC了..
613722008-11-20 17:48:33Accepted 1024 C 16MS928K
总结:出题者的意思其实很明显:1.信息完全有数字组成,2.两个不同的关键字的前4个数字是不相同的,3.如果检索到有关键字出现,则依次输出,
1.即要求我们利用数字来匹配,2.即限制我们匹配的最大的数字不能超过10000,3.即要求程序必须一次循环判断key是否出现。
虽然到最后才知道这个题目怎么搞..不过..哎..考验的就是智力和语文理解能力啊...
我们大家经常用google检索信息,但是检索信息的程序是很困难编写的;现在请你编写一个简单的全文检索程序。问题的描述是这样的:给定一个信息流文件,信息完全有数字组成,数字个数不超过60000个,但也不少于60个;再给定一个关键字集合,其中关键字个数不超过10000个,每个关键字的信息数字不超过60个,但也不少于5个;两个不同的关键字的前4个数字是不相同的;由于流文件太长,已经把它分成多行;请你编写一个程序检索出有那些关键字在文件中出现过。
第一行是两个整数M,N;M表示数字信息的行数,N表示关键字的个数;接着是M行信息数字,然后是一个空行;再接着是N行关键字;每个关键字的形式是:[Key No. 1] 84336606737854833158。
输出只有一行,如果检索到有关键字出现,则依次输出,但不能重复,中间有空格,形式如:Found key: [Key No. 9] [Key No. 5];如果没找到,则输出形如:No key can be found !
初读此题,马上想到C里的strstr()函数,完整匹配,很快代码出来了
V1.0
#include<stdio.h>
#include<string.h>
#define max 60001
char list[max];
int main()
{
char * tp;
int n=0,m=0;
while(EOF!=scanf("%d %d",&n,&m))
{
tp=list;
int i,count=0;
scanf("%s",tp);
while(*tp!='/0')
{
tp++;
count++;
}
for(i=1;i<n;i++)
{
scanf("%s",tp);
if(i==n)
break;
tp+=count;
}
char x=getchar();
int NO,j=0;
int all[10001];
while(m--)
{
x=getchar();
char temp[100];
tp=temp;
scanf("[Key No. %d] %s",&NO,tp);
if(strstr(&list[0],tp)!=NULL)
{
all[j]=NO;
j++;
}
}
int flag=0;
if(j==0)
{
printf("No key can be found !/n");
continue;
}
while(j--)
{
if(flag==0 && list[j]!=0)
{
printf("Found key: [Key No. %d]",all[j]);
flag=1;
}
else
{
printf(" [Key No. %d]",all[j]);
}
}
printf("/n");
}
return 0;
}
提交发现T了,重读此题,发现T的原因可能是strstr函数效率比较低,遂自己重写一个类似strstr()的匹配函数find()
函数初步设计为DP思想,完成代码如下:
V2.0
#include<stdio.h>
#define max 60001
char list[max];
int find(char *fl)
{
int temp[max];
int path[max];
int j=0;
int i=0;
while(list !='/0')
{
if(list==*fl)
{
temp[j]=i;
j++;
}
i++;
}
fl++;
while(*fl!='/0')
{
i=0;
while(j--)
{
if(list[temp[j]+1]==*fl && temp[j]+1<max)
{
path=temp[j]+1;
i++;
}
}
if(i==0)
return -1;
j=i;
while(i--)
{
temp=path;
}
fl++;
}
return 1;
}
int main()
{
char * tp;
int n=0,m=0;
while(EOF!=scanf("%d %d",&n,&m))
{
tp=list;
int i,count=0;
scanf("%s",tp);
while(*tp!='/0')
{
tp++;
count++;
}
for(i=1;i<n;i++)
{
scanf("%s",tp);
if(i==n)
break;
tp+=count;
}
char x=getchar();
int NO,j=0;
int all[10001];
while(m--)
{
x=getchar();
char temp[100];
tp=temp;
scanf("[Key No. %d] %s",&NO,tp);
if(find(tp)!=-1)
{
all[j]=NO;
j++;
}
}
int flag=0;
if(j==0)
{
printf("No key can be found !/n");
continue;
}
while(j--)
{
if(flag==0 && list[j]!=0)
{
printf("Found key: [Key No. %d]",all[j]);
flag=1;
}
else
{
printf(" [Key No. %d]",all[j]);
}
}
printf("/n");
}
return 0;
}
再次提交,发现还是T了,重新读题,还是没明白什么个情况....
最后翻阅前人代码,最后终于发现了问题所在还有题目的具体意思:
程序问题分析:
V1.0在于strstr效率的确是太低
V2.0的DP没有必要,一个是收敛慢,还有一个题目要求输出是否出现而不是出现几次..- -!
题目要求分析:
一.输入流文件信息全为数字
二.两个不同的关键字的前4个数字是不相同的
三.输出出现关键字的标号
可设计程序如下:
取每个关键字前4个数字组成一个4位数存10000长度的数组tp[],匹配流文件的时候每次取4个也组成一个四位数进行匹配,匹配判断即tp【此4位数】是否被标记过,标记过则匹配整个key,仍然全部匹配即可判断匹配存结果数组即可
同理整个流文件一次循环结束即可判断所有key是否匹配。
部分程序如下:
int findall()
{
int i=0,j=0;
int cuo= (list[0]-48)*100 + (list[1]-48)*10 + list[2]-48;
while(list!='/0')
{
cuo=(cuo%1000)*10 + list-48;
if(tpp[cuo] != 0)
{
lenth=i+4;
if( check(chen[tpp[cuo]]) == 1)
{
all[j]=tpp[cuo];
tpp[cuo]=0;
j++;
}
}
i++;
}
return j;
}
程序最终完成,提交AC了..
613722008-11-20 17:48:33Accepted 1024 C 16MS928K
总结:出题者的意思其实很明显:1.信息完全有数字组成,2.两个不同的关键字的前4个数字是不相同的,3.如果检索到有关键字出现,则依次输出,
1.即要求我们利用数字来匹配,2.即限制我们匹配的最大的数字不能超过10000,3.即要求程序必须一次循环判断key是否出现。
虽然到最后才知道这个题目怎么搞..不过..哎..考验的就是智力和语文理解能力啊...