SCAU 11077 最长公共连续子字符串

本文详细阐述了如何运用动态规划(DP)算法解决最长公共子字符串问题,包括算法设计、空间优化以及实现细节。通过实例分析,读者可以深入了解如何在字符串长度达到10^5的情况下,有效地寻找两个输入序列的最长公共子字符串及其长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

初级入门DP,感觉有点难招架,已经看了MIT算法导论就关于DP的视频有两遍了,逛逛飞燕社区也找了一下相关的资料,今早愣在机房尽想着写状态转移方程,最后还是只写了那么一条:dp[i, j] = a[i] == b[i] ? dp[i-1][j-1]+1 : 0; 串的长度达到了10^5,目测开到二维应该不行了,后来翻看算法导论的讲解视频,跪了,后面缩减空间的内容都忘了~~

11077 最长公共子字符串

时间限制:1000MS  内存限制:65535K

题型: 编程题   语言: 无限制

Description

求两个输入序列的最长的公共子字符串的长度。子字符串中的所有字符在源字符串中必须相邻。

如字符串:21232523311324和字符串312123223445,他们的最长公共子字符串为21232,长度为5。

输入格式

两行,第一行为第一个字符串X,第二行为第二个字符串Y,字符串不含空格并以回车标示结束。X和Y的串长都不超过100000

输出格式

两行,第一行为最长的公共子字符串的长度,第二行输出一个最长的公共子字符串。

说明:
(1)若最长的公共子字符串有多个,请输出在源字符串X中靠左的那个。
(2)若最长公共子字符串的长度为0,请输出空串(一个回车符)。

如输入:
21232523311324
152341231
由于523和123都是最长的公共子字符串,但123在源串X中更靠左,因此输出:
3
123

输入样例

21232523311324
312123223445

输出样例

5
21232

作者

zhengchan

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define MAXN 100010
 4 char a[MAXN], b[MAXN];
 5 int p[MAXN], q[MAXN];
 6 
 7 int main()
 8 {
 9 //    freopen("input.txt", "r", stdin);
10     int i, j, len_a, len_b, sum, x, y;
11     scanf("%s%s", a, b);
12     len_a = strlen(a);
13     len_b = strlen(b);
14     memset(p, 0, sizeof(p));
15     memset(q, 0, sizeof(q));
16     sum = 0;
17     for(i=0; i<len_a; ++i)
18     {
19         memcpy(q, p, sizeof(int)*len_b);
20         memset(p, 0, sizeof(p));
21         for(j=0; j<len_b; ++j)
22         {
23             if(a[i] == b[j])
24             {
25                 if(j == 0) p[j] = 1;
26                 else p[j] = q[j-1]+1;
27                 if(sum < p[j])
28                 {
29                     x = j;
30                     sum = p[j];
31                 }
32             }
33         }
34     }
35     printf("%d\n", sum);
36     a[sum--] = '\0';
37     for( ; sum>=0; --sum, --x)
38     a[sum] = b[x];
39     printf("%s\n", a);
40     return 0;
41 }

 

转载于:https://www.cnblogs.com/liaoguifa/archive/2013/04/19/3031725.html

### 寻找最长回文串的算法实现 #### 中心扩散法简介 中心扩散法是一种用于寻找最长回文子串的有效方法。该方法通过遍历字符串中的每一个字符作为潜在的回文中心,向两侧扩展来找到最大长度的回文子串[^2]。 对于奇数长度的回文串,中心是一个单独的字符;而对于偶数长度的回文串,则存在两个相邻字符组成的中心。为了处理这两种情况,在每次迭代时都需要尝试两种不同的中心位置并记录更长的那个结果。 #### Python代码示例 下面提供了一个基于上述原理编写的Python函数`longest_palindromic_substring()`: ```python def longest_palindromic_substring(s: str) -> str: if not s or len(s) == 0: return "" start, end = 0, 0 for i in range(len(s)): len1 = expand_around_center(s, i, i) len2 = expand_around_center(s, i, i + 1) max_len = max(len1, len2) if max_len > end - start: start = i - (max_len - 1) // 2 end = i + max_len // 2 return s[start:end + 1] def expand_around_center(s: str, left: int, right: int) -> int: L, R = left, right while L >= 0 and R < len(s) and s[L] == s[R]: L -= 1 R += 1 return R - L - 1 ``` 此代码定义了辅助函数 `expand_around_center()`, 它接受三个参数:原始字符串`s`以及表示可能成为回文中点的一对索引值`left` 和 `right`. 函数返回从这对索引向外扩展开来的有效回文部分的最大宽度. 主函数则利用这个工具去计算整个输入字符串内的最佳解,并最终输出对应的字串片段.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值