poj 3080 kmp

思路:思维定势想到用后缀数组,结果行不通。其实枚举第一个字符串的子串作为模式串,然后对后面n-1个字符串进行kmp匹配,这样的复杂度为O(L^3)
 
 
 
  1.  #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. const int N = 70, M = 15;
  5. int ls, lp, pre[N], len;
  6. char str[M][N], s2[N], ans[N];
  7. void prefix(char *p)
  8. {
  9.  int i, k;
  10.  memset(pre, 0, sizeof(pre));
  11.  pre[1] = 0;
  12.  k = 0;
  13.  for(i = 2; i <= lp; i++)
  14.  {
  15.   while(k > 0 && p[k+1] != p[i]) k = pre[k];

  16.   if(p[k+1] == p[i]) k++;
  17.   pre[i] = k;
  18.  }
  19. }
  20. bool kmp(char *p, char *s)
  21. {
  22.  int i, k, cnt = 0;

  23.  k = 0;
  24.  for(i = 1; i <= ls; i++)
  25.  {
  26.   while(k > 0 && p[k+1] != s[i]) k = pre[k];

  27.   if(p[k+1] == s[i]) k++;
  28.   if(k == lp)
  29.   {
  30.    // cnt++;
  31.     // k = pre[k];
  32.    return true;
  33.   }
  34.  }
  35.  return false// also cnt
  36. }
  37. int main()
  38. {
  39.  int t, n, i, j;
  40.  scanf("%d/n", &t);
  41.  while(t--)
  42.  {
  43.   scanf("%d", &n);
  44.  for(i = 0; i < n; i++) scanf("%s", str[i]+1);

  45.  len = 0;
  46.  strcpy(ans, "no significant commonalities");
  47.  for(lp = 60; lp >= 3; lp--)
  48.  {
  49.   for(i = 1; i+lp-1 <= 60; i++)
  50.   {
  51.    prefix(str[0]+i-1);
  52.    ls = 60;
  53.    for(j = 1; j < n; j++)
  54.    {
  55.     if(!kmp(str[0]+i-1, str[j])) break;
  56.    }
  57.    if(j >= n && lp >= len)
  58.    {
  59.     strncpy(s2, str[0]+i, lp);
  60.     s2[lp] = 0;

  61.     if(lp>len || lp==len && strcmp(s2, ans)<0)
  62.     {
  63.      strcpy(ans, s2);
  64.     }
  65.    }
  66.   }
  67.   if(strcmp(ans,"no significant commonalities")!=0)break;
  68.  }

  69.  puts(ans);
  70.  }
  71.  return 0;
  72. }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值