zoukankan      html  css  js  c++  java
  • hdu 1238 Substrings 解题报告

        题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1238

        题意很简单,即找出最长的公共子串。

      n个序列为p[0]...p[n-1],最长公共子串(顺着看,存放在p[0])的长度为maxlen,逆着看(存放在reverse数组里)的长度为maxlen1。由于公共子序列是每个序列的子串,因此不妨枚举第一个序列(其实枚举最短的那个子串是最好的)的每一个可能的子串s,以s为模式,分别以p[1]...p[n-1]为目标进行匹配计算。若s为p[1]...p[n-1]的公共子串(strstr[p[k], s) != 0,1  <=  k  <=  n-1),且串的长度>maxlen(或者maxlen1),则将s调整为最长公共子串(maxlen(maxlen1) = s串的长度)。最后比较maxlen和maxlen1的长度,大的那个即是答案。

        计算子串匹配时采用了Brute Force算法(存在着大量的重复运算,KMP算法可以提高匹配时效)。另外使用了一些字符串库函数,例如字符串长度函数strlen(),比较字符串大小的函数strcmp(),字符串复制函数strcpy()等。

       

     1 #include <iostream>
     2 #include <string.h>
     3 using namespace std;
     4 
     5 char p[105][105];
     6 char reverse[105];
     7 char s[105];
     8 
     9 int main()
    10 {
    11     bool ok;
    12     int t, n, i, j, k, l, len, maxlen, maxlen1;
    13     while (cin >> t)
    14     {
    15         while (t--)
    16         {    
    17             memset(s, 0, sizeof(s));
    18             cin >> n;
    19             for (i = 0; i < n; i++)     // 输入第i个序列
    20                 cin >> p[i];
    21             len = strlen(p[0]);
    22             l = len - 1;
    23             maxlen = maxlen1 = 0;     // 最长公共子串的长度
    24             for (i = 0; i < len; i++)       // 枚举子串的起始位置i
    25             {
    26                 reverse[l--] = p[0][i];     // 存放第一个序列的逆序列
    27                 for (j = i; j < len; j++)    // 枚举子串的结束位置j 
    28 { 29 strncpy(s, p[0]+i, j-i+1); // 提取该子串s 30 s[j-i+1] = '\0'; 31 ok = true; // 试探s是否为p[1]...p[n-1]的公共子串 32 for (k = 1; ok && k < n; k++) 33 { 34 if (strstr(p[k], s) == 0) // 如果找到一条序列不是以当前s为子串,则枚举下一条新的子串s 35 ok = false; 36 } 37 if (ok && maxlen < j-i+1) // s是所有序列的公共子串,且s串的长度 > maxlen,则将maxlen调整为s串的长度 38 maxlen = j - i + 1; 39 } 40 } 41 for (i = 0; i < len; i++) // 第一个子串的逆序时的处理,与顺序时的处理相同 42 { 43 for (j = i; j < len; j++) 44 { 45 strncpy(s, reverse+i, j-i+1); 46 s[j-i+1] = '\0'; 47 ok = true; 48 for (k = 1; ok && k < n; k++) 49 { 50 if (strstr(p[k], s) == 0) 51 ok = false; 52 } 53 if (ok && maxlen1 < j-i+1) 54 maxlen1 = j - i + 1; 55 } 56 } 57 printf("%d\n", (maxlen1 > maxlen ? maxlen1 : maxlen)); // 比较顺序和逆序时哪个子串的长度大 58 } 59 } 60 return 0; 61 }
  • 相关阅读:
    Temporal Action Detection with Structured Segment Networks (ssn)【转】
    ubuntu多版本cuda并存与切换【两个博客链接】
    TURN TAP: Temporal Unit Regression Network for Temporal Action Proposals(ICCV2017)
    CTAP: Complementary Temporal Action Proposal Generation (ECCV2018)
    很实用的HTML5+CSS3注册登录窗体切换效果
    基于js的网页换肤(不需要刷新整个页面,只需替换css文件)
    CSS重置 reset.css
    CSS3制作分步注册表单
    CSS3 3D立体柜子实现
    创建 CSS3 下拉菜单
  • 原文地址:https://www.cnblogs.com/windysai/p/3082509.html
Copyright © 2011-2022 走看看