Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1006655
  • 博文数量: 150
  • 博客积分: 3017
  • 博客等级: 少校
  • 技术积分: 3829
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-19 14:40
个人简介

Now in Baidu WISE team

文章分类

全部博文(150)

文章存档

2014年(8)

2013年(31)

2012年(111)

分类: C/C++

2012-11-01 22:08:16

一篇文章,切完词之后放到一个vector中,一个查询切完词也放到一个vector中,写一个函数找出这篇文章中包含这个查询中所有词的最小区间的i和j。只要返回第一个即可。

这是一个很有实用价值的题目。在搜索引擎中,我们如果搜索了几个关键字,那么在搜索结果中每个条目,都会显示包含所有关键字的一段很短的文字的summary.

这个题看到稍微分析了下就感觉和首尾相连的珠子的那道题类似。

假设有k个关键字,文本长度是n,那么最后算法复杂度是 O(nk).

解析:
a.假设有文本text,长度为len,有K个关键字存储在数组keys[K]
b.我们用函数f(n,k) 来表示从文本text中下标为n处开始,keys[k]这个关键字结束的位置的下一个.如果找不到,记录为-1.
           例如test = "abcab",keys[2] = "ab" 
           那么有f(0,2) = 2; f(1,2) = 5; f (2,2) = 5 ....

c.那么,从text的位置n开始,覆盖所有关键字的一段,其截至位置
           g(n) =   max{f(n,0), f(n,1)... f(n,K)} ;
 
我们从0~ len-1全部循环,就可以得出从每个位置开始,向后延伸,覆盖所有关键字的最短文本截至的位置。
再从中输出最短的一段即可。

优化:
在b步骤,我们可以直接使用strstr函数,但是这里,f(0,2) = 2, f(1,2) =5算出这两个的时候,显然我们就不用strstr就可以知道 f(2,2) f(3,2) 的值必定都为5.
在c步骤,我们从0~ len-1循环,如果某个位置t开始,有关键字m, 使得f(t,m) = -1,说明从t位置之后,关键字m就不再出现了,所有再往后,就不可能出现覆盖所有关键字的循环了。这时,可以直接跳出。


代码:
因为感觉比较麻烦,这个代码没有实现第一个优化。

点击(此处)折叠或打开

  1. /*
  2.  * =====================================================================================
  3.  *
  4.  * Filename: summary.c
  5.  *
  6.  * Description:
  7.  *
  8.  * Version: 1.0
  9.  * Created: 11/01/2012 09:20:25 PM
  10.  * Revision: none
  11.  * Compiler: gcc
  12.  *
  13.  * Author: royn.wang.renyuan@gmail.com (),
  14.  * Organization:
  15.  *
  16.  * =====================================================================================
  17.  */
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <stdio.h>
  21. #define MAX 100000
  22. #define KMAX 10
  23. int keysindex[MAX][KMAX];
  24. int result[MAX] = {0};
  25. void Getkeysindex(char* input, char* keys[], int keycount){
  26.     int k = 0;
  27.     for(;k<keycount;k++){
  28.         int i = 0;
  29.         for(;i<strlen(input);i++){
  30.             char *t = strstr(input+i, keys[k]);
  31.             if(t!=NULL){
  32.                 keysindex[i][k] = t - input + strlen(keys[k]) -1;
  33.             }
  34.             else{
  35.                 keysindex[i][k] = -1;
  36.             }
  37.         }
  38.     }
  39. }
  40. void Match(int keycount, int len){
  41.     int i = 0;
  42.     int k;
  43.     int result[MAX] = {0};
  44.     for(;i<len;i++){
  45.         for(k = 0;k<keycount;k++){
  46.             if(keysindex[i][k] == -1){
  47.                 result[i] = -1;
  48.                 return;
  49.             }
  50.             result[i] = (result[i] > keysindex[i][k] ? result[i] :keysindex[i][k]);
  51.         }
  52.         printf ( "start: %d end: %d len: %d\n", i, result[i], result[i]-i +1);
  53.     }
  54. }

  55. /*
  56.  * === FUNCTION ======================================================================
  57.  * Name: main
  58.  * Description:
  59.  * =====================================================================================
  60.  */
  61.     int
  62. main ( int argc, char *argv[] )
  63. {
  64.     char *text = "ababcd";
  65.     char *keys[] = {"ab", "bc", "cd"};
  66.     Getkeysindex(text,keys,sizeof(keys)/sizeof(void*));
  67.     Match(sizeof(keys)/sizeof(void*),strlen(text));
  68.     return EXIT_SUCCESS;
  69. }                /* ---------- end of function main ---------- */

阅读(1023) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~