Rqnoj164 最长公共字串 题解
依然是一道搜索题,但是类似动态规划的写法很简单,贴在这里。
【题目描述】(rqnoj164) Saltless截获了两个序列,序列A和B,规定两个序列所隐藏的信息就是两者的最长公共子串(注意,这里的子串是指连续的,比如说ABCDEFG中ABC是ABCDEFG的子串,而ABD或者ABE都不是ABCDEFG的子串),现在,他将这个任务交给你,你要找出这两个序列所隐藏的信息 【输入格式】 两行,A和B(AB长度均不大于1000,AB均由大写字母组成,且AB长度相等) 【输出格式】 一个序列,表示A和B的最长公共子串(若有多个最长子串,则输出最先出现的一个,数据保证存在解) 【样例输入】 ABCDE ABDEC 【样例输出】 AB
方法很简单,从头开始扫描两个串,判断相应位置i,j对应的s1[i],s1[j]是否相等。因为公共部分必须是连续的,所以只用把当前的最优解赋值为f[i-1,j-1]+1,即i,j都往前推一位的最优解加上1即可。
根据样例来说,f[1,1]=1,f[2,2]=f[1,1]+1=2,而f[3,3]因为s1[3]<>s2[3],所以不更新。
参考代码:
1 program pubstr;
2 var
3 s1,s2:array[1..1000]of char;
4 l:integer;
5 f:array[0..1001,0..1001]of integer;
6 i,j,max,x:integer;
7 begin
8 while not eoln do
9 begin
10 inc(l);
11 read(s1[l]);
12 end;
13 readln;
14 for i:=1 to l do
15 read(s2[i]);
16 max:=0;
17 for i:=1 to l do
18 for j:=1 to l do
19 if s1[i]=s2[j] then
20 begin
21 f[i,j]:=f[i-1,j-1]+1;
22 if max<f[i,j] then //因为最优解的位置不定,所以要记录位置
23 begin
24 max:=f[i,j];
25 x:=i; //x记录公共子串的尾坐标
26 end;
27 end;
28 for i:=x-max+1 to x do
29 write(s1[i]);
30 end.
(saltless原创,转载请注明出处)