pku 1226 Substrings

转的:

题意:输入n个字符串,每个字符串的长度最多为100,要求求出这n个字符串的最长公共子串长度。(注意:假设这n个字符的最长公共子串为maxstr,则说每个字符串的的正序或逆序中只要其中一个有maxstr,就说明该字符含有maxstr).

思路:(1)先求这n个字符串中的最小长度字符串minstr.

            (2)再枚举公共子串的长度从len(minstr) 到 1,枚举所有可能的公共子串substr,再检查其它n - 1个字符串中的正序或逆序串中是否有substr,如果满足,则返回长度len(substr),否则继续枚举,直到长度为0.

          (3)strstr, strncpy函数的应用很重要,大家可上网查相应的用法。

源代码:

#include <iostream> //此代码参考了网上资料
using namespace std;
const int MAXN = 101;
char str[MAXN][MAXN];
void my_strrev(char *str)
{
      int l, r;
      r = strlen(str);
      l = 0; r = r - 1;
      while(l < r) {
            char ch = str[l];
            str[l ++] = str[r];
            str[r --] = ch;
      }
}
int max_substr(char *source, int n)
{
      int sublen = strlen(source);
      int sourcelen = strlen(source);
      char substr[MAXN], resubstr[MAXN];
      while(sublen > 0) {
            for(int i = 0; i <= sourcelen - sublen; i ++) {
                  strncpy(substr, source + i, sublen);
                  strncpy(resubstr, source + i, sublen);
                  substr[sublen] = '/0';
                  resubstr[sublen] = '/0';
                  my_strrev(resubstr);
                  bool flag = true;
                  for(int j = 0; j < n; j ++)
                        if(strstr(str[j], substr) ==NULL
                            && strstr(str[j], resubstr) == NULL) {
                                   flag = false; break;
                            }
                  if(flag) return(sublen);
            }
            sublen --;
      }
      return(0);
}
int main()
{
      char minstr[MAXN];
      int i, j, n, minlen, test;
      scanf("%d", &test);
      while(test --) {
           scanf("%d", &n);
           getchar();
           minlen = 100;
           for(i = 0; i < n; i ++) {
                 scanf("%s", str[i]);
                 if(minlen>strlen(str[i])) {
                       minlen = strlen(str[i]);
                       strcpy(minstr, str[i]);
                 }
           }
           printf("%d/n", max_substr(minstr, n));
      }
      return(0);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值