NIT-OJ-1024-全文检索-解题报告

描述:
我们大家经常用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是否出现。

虽然到最后才知道这个题目怎么搞..不过..哎..考验的就是智力和语文理解能力啊...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值