Chinaunix首页 | 论坛 | 博客
  • 博客访问: 69823
  • 博文数量: 115
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-08 19:09
文章分类
文章存档

2015年(115)

我的朋友

分类: C/C++

2015-08-06 16:49:46

有n个长为m+1的字符串,如果某个字符串的最后m个字符与某个字符串的前m个字符匹配,则两个字符串可以联接,问这n个字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误。

这是一个看着容易做起来难的题。如果真是面试的时候,或许能想到算法,但是要现场写出能run的代码,实在无能为力。。。

1.建立一个struct, 每个串对应一个。value是串的内容。count是它的后面能够链接的字符串的个数。然后一个children数组,存储每个它后面能够连接的字符串的结构体。

2.预处理所有数据,处理每个输入,转成上面定义的结构体,列出每个串后面能与他链接的字符串,以及满足条件个数。为处理方便,让所有结构体连续存储,这样可以简单遍历。

3.可以想象,所有的结构体最后组成了一个图,连通或者不联通。这个问题就转化为求这个图中距离最远的两个点的距离。这里,运用了动态规划的想法,避免了重复对某个点进行尝试。

4. 用一个数组result存储每个串最长能链接的个数。初值为0. 对于一个串str, result[str]就是它能拼接的最大长度。

5. 遍历2中得到的数组。
  a. 对于一个元素elem,如果他的count不为0,那么说明有串能接在他的后面.若没有,那么它后面不能拼接任何串,result[elem] = 1。
  b. 遍历它children,对于其中的一个后缀连接(tailstr),看result数组中这个tailstr对应的值是否为0
       I.如果不为0,说明后续长度就是result[tailstr],那么当前元素elem和tailstr的拼接的最大长度就是tmp=result[tailstr]+1.直到遍历完成,记录tmp达到的最大值,那么当前元素elem能链接的串最长就是tmp个.写入result数组result[elem] = tmp.
       II.如果为0,说明这个串还没被处理过,那么递归调用b.

6. 必须保证每个串都被处理一遍。完成之后,算法结束。
 
7.为了发现环的问题,还需要引入一个变量,记录递归嵌套的深度,如果深度超过了输入字符串的个数了,那么说明有环,直接返回-1.

7。最后便利result数组,就能得出可能达到的最长的长度。当然,也可以设置一个全局变量记录最大值max,每次往result里面写的时候,和max比较,如果当前写入值更大那么就更新max.这样可以少一次循环。

复杂度分析:
在预处理阶段,对与一个串,显然是要比n次。所以预处理的复杂度为O(n^2);
找出最长路径的算法,每个点如果得出结果了,那么就存入result,下次就不需要再处理了。所以一个点只处理1次。这个复杂度应该是O(n);

因为用c实现,所以没有keyvaluepair之类的数据结构,只能用一个连续数组来存储结构体,这样就导致了没法通过串的值当作key来索引。 因此result用了蹩脚的地址偏移量来获取下标。

点击(此处)折叠或打开

  1. /*
  2.  * =====================================================================================
  3.  *
  4.  * Filename: strcombine.c
  5.  *
  6.  * Description:
  7.  *
  8.  * Version: 1.0
  9.  * Created: 10/05/2012 10:30:18 AM
  10.  * Revision: none
  11.  * Compiler: gcc
  12.  *
  13.  * Author: YOUR NAME (),
  14.  * Organization:
  15.  *
  16.  * =====================================================================================
  17.  */
  18. #include <stdlib.h>
  19. #include    <stdio.h>

  20. #define MAX 1000
  21. #define LEN 3
  22. typedef struct tagword{
  23.     const char *value;
  24.     int count;
  25.     struct tagword* children[MAX];
  26. } word;

  27. int Size;
  28. int result[MAX]= {0};
  29. word* Base;

  30. char IsMatch(const char* src, const char* pattern){
  31.     int i = 0;
  32.     for(;i<LEN-1;i++){
  33.         if(*(src+i+1) != *(pattern+i)) return 0;
  34.     }
  35.     printf ( "%s matched %s\n", src, pattern );
  36.     return 1;
  37. }

  38. word* prepare(char **input, int size){
  39.     word* head = (word *)malloc(sizeof(word) * size);
  40.     int i = 0;
  41.     for(;i<size;i++){
  42.         head[i].value = input[i];
  43.         head[i].count = 0;
  44.     }
  45.     for(i=0;i<size;i++){
  46.         int m = 0;
  47.         for(;m<size;m++){
  48.             if( m!=i && IsMatch(head[i].value, head[m].value)){
  49.                 (head[i].children)[head[i].count++] = &head[m];
  50.             }
  51.         }
  52.     }
  53.     return head;
  54. }
  55. int track(word* head, int dep){
  56.     if(dep > Size) return -1;
  57.     int i = 0;
  58.     dep++;
  59.     int tmp = 0;
  60.     if(result[head-Base] != 0){
  61.         return result[head-Base];
  62.     }
  63.     for(;i < head->count; i++){
  64.         printf ( "tracking child %s\n",(head->children[i])->value );
  65.         int cdep = track(head->children[i], dep);
  66.         if(cdep == -1) return cdep;
  67.         if(tmp < cdep) tmp = cdep;
  68.         
  69.     }
  70.     tmp++;
  71.     printf ( "%d -> %d \n", head-Base, tmp );
  72.     result[head-Base] = tmp;
  73.     return tmp;
  74.     
  75. }

  76. /*
  77.  * === FUNCTION ======================================================================
  78.  * Name: main
  79.  * Description:
  80.  * =====================================================================================
  81.  */
  82.     int
  83. main ( int argc, char *argv[] )
  84. {
  85.     char * input[]= {"bcd","cde","def", "abc","deg","egh"};
  86.     Size = sizeof(input)/(LEN+1);
  87.     word* head = prepare(input, Size);
  88.     Base = head;
  89.     int i = 0;
  90.     for(;i<Size; i++){
  91.         track(head++,0);
  92.     }
  93.     int max = 0;
  94.     for(i = 0; i<Size; i++){
  95.         max = max>result[i]?max:result[i];
  96.         printf ( "%d \n", result[i] );
  97.     }
  98.     printf ( "max length is %d\n", max );
  99.     return EXIT_SUCCESS;
  100. }                /* ---------- end of function main ---------- */

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