编程之美——最短摘要的生成

编程之美——最短摘要的生成

题目:

    最短摘要的生成,具体见《编程之美》这本书。

分析:

    先来看看这些序列:

w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q0,w9,q1

     问题在于,如何一次把所有的关键词都扫描到,并且不遗漏。扫描肯定是无法避免的,但是如何把两次扫描的结果联系起来呢?这是一个值得考虑的问题。

     沿用前面的扫描方法,再来看看。第一次扫描的时候,假设需要包含所有的关键词,从第一个位置w0处将扫描到w6处:

w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q0,w9,q1

     那么,下次扫描应该怎么办呢?先把第一个被扫描的位置挪到q0处。

w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q0,w9,q1

     然后把第一个被扫描的位置继续往后面移动一格,这样包含的序列中将减少了关键词q0。那么,我们便可以把第二个扫描位置往后移,这样就可以找到下一个包含所有关键词的序列。即从w4扫描到w9处,便包含了q1,q0:

w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q0,w9,q1

     这样,问题就和第一次扫描时碰到的情况一样了。依次扫描下去,在w中找出所有包含q的序列,并且找出其中的最小值,就可得到最终的结果。

代码为:
#include “stdio.h”
#include “string.h”
#include “assert.h”
#define MAX 1024
int isMatchAll(const char *str,const char *key,int begin,int end)
{
  int ret=0;
  char hash[256];
  int i=0;
  int lenK=strlen(key);
  memset(hash,0,sizeof(hash));
  for(i=begin;i<=end;i++)
  {
    hash[str[i]]=1;
  }
  for(i=0;i<lenK;i++)
  {
    if(hash[key[i]]==0)
break;
  }
  if(i==lenK)
 ret=1;
  return ret;
}

void find(const char *str,const char *key)
{
  if(str==NULL&&key==NULL)
 return;
  int lenS=strlen(str);
  int lenK=strlen(key);
  int begin=0;
  int end=0;
  int minLength=0x7FFFFFFF;
  int mstart=0;
  int mend=0;
  for( ; ; )
  {
    while(!isMatchAll(str,key,begin,end)&&end<lenS)
{
end++;
}
while(isMatchAll(str,key,begin,end))
{
 if(end-begin+1<minLength)
 {
   minLength=end-begin+1;
mstart=begin;
mend=end;
 }
 begin++;
}
if(end>=lenS)
break;
  }
  printf(“%d\n”,minLength);
  for(;mstart<=mend;mstart++)
     printf(“%c\n”,str[mstart]);
}

int main()
{
  char str[MAX];
  char key[MAX];
  gets(str);
  gets(key);
  find(str,key);
  return 0;
}

    原文作者:快乐的霖霖
    原文地址: https://blog.csdn.net/chdhust/article/details/8298377
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞