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

Now in Baidu WISE team

文章分类

全部博文(150)

文章存档

2014年(8)

2013年(31)

2012年(111)

分类: C/C++

2012-10-19 15:41:32

给定一个字符串集作为字典,例如{"cal","calf","calfs","call","calls","choral","chorale","coal","coral"}
然后给出初始字符串cal.
对于一个字符串,如果在字典中存在一个串,只需要在串内添加一个字符就可以构成,那么我们就扩展该串。
比如对于cal, 可以扩展成calf,call, coal。
求一个给定串,在给定的字典内,最长可以扩展到哪个字符串。
上面给出的数据中,最长的扩展串是chorale.
路径为
cal, coal, coral, choral, chorale
原题地址:


Sample Input

9 cal
cal
calf
calfs
call
calls
choral
chorale
coal
coral

Sample Output

chorale


解法:
一个串当做一个节点,如果一个串可以扩展成另一个串,那么说明他们之间有一条有向边。那么这道题其实就是求从第一个点开始,能到达的最远的点。类似图的最长路径。
给定字典Dic[MAX];
对于一个长度为n的串s.如果它有扩展串:
      f(s).next为它所有可扩展成的串中, 最终长度最长的那一组中,它下个串的下标。
      f(s).max为它所有可扩展成的串中, 最长能扩展到次数
例如对于cal, 有多个扩展串,calf call coal,根据最后结果,
     f(cal).next为coal在字典中的下标。
     f(cal).max 为chorale的长度。

那么对于一个长度为n-1的串 str, 它的扩展串为extend1,extend2 .. extendp
     f(str).max = max{f(extend1).max, f(extend2).max .... f(extendp).max} + 1;
     f(str).next = ex  ( ex为str扩展串中,f(extend).max最大的那个)

如果没有扩展串,那么f(s).next = -1; f(s).max = 1;
当字典中所有的串都被遍历过一遍,即可找出每个串最后能扩展成的最长的串。

优化:
 可以使用一个几个结构体,将每个串和它的扩展串组织起来。然后对数据进行预处理。这样每次获取扩展串时,只需要从children里取就行了。 复杂度可以减少一个n.
代码中还没实现这个优化。
struct word{
     char* str;
     int   children[MAX];
}

代码:

点击(此处)折叠或打开

  1. #include <stdlib.h>
  2. #include <stdio.h>

  3. #define MAXCON 1000
  4. #define MAXLEN 80

  5. int result[MAXCON][2]= {{0}};
  6. int isNext(const char* src, const char *next){
  7.     const char *s = src;
  8.     const char *n = next;
  9.     int couter = 0;
  10.     while((*s || *n) && couter<=1){
  11.         if(*s != *n){
  12.             couter ++;
  13.             n++;
  14.             continue;
  15.         }
  16.         s++;
  17.         n++;
  18.     }
  19.     return couter;
  20.     //if is next result 1
  21.     //else return 0;
  22. }
  23. void test(char* input[], int* lens, int count){
  24.     int len = MAXLEN;
  25.     int i;
  26.     for(;len>=3; len--){
  27.         for(i=0;i<count;i++){
  28.             //tracking the str, whose length is len
  29.             if(lens[i] == len){
  30.                 //printf("tracking %s \n", input[i]);
  31.                 //record the max len
  32.                 int max = 1;
  33.                 int next = -1;
  34.                 int t = 0;
  35.                 for(;t<count;t++){
  36.                 //    printf("--- %s \n",input[t]);
  37.                     //if a words length is len+1 then check whether they can join.
  38.                     if(lens[t] == len+1 && isNext(input[i],input[t] )== 1){
  39.                         if(max<(1+result[t][0]) ){
  40.                             max =1+result[t][0];
  41.                             next = t;
  42.                         }
  43.                     }
  44.                 }
  45.                 result[i][0] = max;
  46.                 result[i][1] = next;
  47.                 printf("(%d) %s : next = %d, len = %d\n", i,input[i], next, max);
  48.             }
  49.         }
  50.     }


  51. }

  52. int main(){
  53.     char * input[] ={"cal","calf","calfs","call","calls","choral","chorale","coal","coral"};
  54.     int size = sizeof(input)/sizeof(void*);
  55.     int tar = 0;
  56.     int lens[size] ;
  57.     int i;
  58.     for(i=0; i<size; i++){
  59.         lens[i] = strlen(input[i]);
  60.         printf("len[%d] = %d \n",i, lens[i]);
  61.     }
  62.     test(input, lens, size);
  63.     while(result[tar][1]!=-1)
  64.         tar = result[tar][1];
  65.         printf("%s\n", input[tar]);
  66.     return 0;
  67. }






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