hdu 1841 Find the Shortest Common Superstring
2013-04-18 17:44
239 查看
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1841
本题的意思就是给出两个字符串,看一下能组成最短的串的长度,当然只能首尾连接
这题也是对KMP的应用,主要还是对next数组的的求解
这题大概应该有两个地方需要注意的
1.开始写这题我直接就把串连接为S=S1+S2和S=S2+S1这两种情况,然后比较取S串最短的那种
比如样例中alba和bacau,则可以组成alba(ba)cau和串bacaualba显然前者组合方式可以取得最短串S
对于判断过程,则可以考察串s1的前缀和s2的后缀或者是s1的后缀和s2的前缀最大匹配程度,这个过程中就可以将他们连接到一个
串S中,求出S的next数组,进而判断他们的匹配程度。以上思路少考虑了一种情况,我在这里WA了一次,就是可能一个短串s1可能包含在长串s2
中,这种情况下只需要输出最长串的长度
2.第二个问题就是个小问题了,可能也就我会出现疏忽,就是在strcat(s1,s2)后,s1发生了改变,下次不能连接strcat(s2,s1),可以分别把它们另存一下,以便第二次连接
还有一个就是这题多次调用KMP函数getnext,开始对这点处理的很不好,写了好几个函数,后来学会传参数的时候把字符串对应的长度也传过去,就会减少不必要的麻烦
代码如下
View Code
另推荐一篇介绍KMP的文章,感觉很不错http://www.cnblogs.com/wentfar/archive/2011/12/17/2291340.html
本题的意思就是给出两个字符串,看一下能组成最短的串的长度,当然只能首尾连接
这题也是对KMP的应用,主要还是对next数组的的求解
这题大概应该有两个地方需要注意的
1.开始写这题我直接就把串连接为S=S1+S2和S=S2+S1这两种情况,然后比较取S串最短的那种
比如样例中alba和bacau,则可以组成alba(ba)cau和串bacaualba显然前者组合方式可以取得最短串S
对于判断过程,则可以考察串s1的前缀和s2的后缀或者是s1的后缀和s2的前缀最大匹配程度,这个过程中就可以将他们连接到一个
串S中,求出S的next数组,进而判断他们的匹配程度。以上思路少考虑了一种情况,我在这里WA了一次,就是可能一个短串s1可能包含在长串s2
中,这种情况下只需要输出最长串的长度
2.第二个问题就是个小问题了,可能也就我会出现疏忽,就是在strcat(s1,s2)后,s1发生了改变,下次不能连接strcat(s2,s1),可以分别把它们另存一下,以便第二次连接
还有一个就是这题多次调用KMP函数getnext,开始对这点处理的很不好,写了好几个函数,后来学会传参数的时候把字符串对应的长度也传过去,就会减少不必要的麻烦
代码如下
View Code
# include <stdio.h> # include <string.h> # define NN 1000001 char s1[NN*2],s2[NN*2],s3[NN*2],s4[NN*2]; int len1,len2,len; int next[NN*2]; void getnext(char *P,int L) { int i=0,j=-1; next[0]=-1; while(i<L) { if(j==-1 || P[i]==P[j]) { ++i; ++j; next[i]=j; } else j=next[j]; } } int KMP(char *S,char *P, int LS,int LP) { int i=0, j=0; getnext(P,LP); while(i<LS && j<LP) { if(j==-1 || S[i]==P[j]) { ++i; ++j; } else j=next[j]; } if(j==LP) return 1; return 0; } int main() { int t, flag; scanf("%d",&t); while(t--) { int sum1,sum2,k; flag=0; scanf("%s %s",s1,s2); strcpy(s3,s1); //拷贝字符串以便在下面交换连接s1和s2 strcpy(s4,s2); len1 = strlen(s1); len2 = strlen(s2); len = len1 + len2; if(len1 <= len2) //这里判断长子串是否包含短子串 { flag = KMP(s2,s1,len2,len1); if(flag==1) printf("%d\n",len2); } else if(len1 > len2) { flag = KMP(s1,s2,len1,len2); if(flag==1) printf("%d\n",len1); } if(flag==0) //这里对一般情况进行处理,即不是互相包含 { strcat(s1,s2); //先将s2连接至s1 getnext(s1,len); int k = len; while(next[k]>len1 || next[k]>len2) k=next[k]; if(next[k]==0) sum1=len; else { sum1 = len-next[k]; } strcat(s4,s3); //将s1连接至s2 getnext(s4,len); k = len; while(next[k]>len1 || next[k]>len2) k=next[k]; if(next[k]==0) sum2=len; else { sum2 = len-next[k]; } if(sum1<=sum2) printf("%d\n",sum1); else printf("%d\n",sum2); } } return 0; }
另推荐一篇介绍KMP的文章,感觉很不错http://www.cnblogs.com/wentfar/archive/2011/12/17/2291340.html
相关文章推荐
- HDU 1841 Find the Shortest Common Superstring----KMP
- hdu 1841 Find the Shortest Common Superstring
- HDU 1841 Find the Shortest Common Superstring
- HDU 1841 Find the Shortest Common Superstring(KMP 理解 应用 求组合串的next值判断是否匹配)
- HDU 1841 Find the Shortest Common Superstring
- HDU1841 Find the Shortest Common Superstring (KMP两字符串的首尾连接)
- HDU 1841 Find the Shortest Common Superstring(KMP)
- HDU 1841: Find the Shortest Common Superstring
- HDU 1841 Find the Shortest Common Superstring(KMP灵活运用)
- 文章标题 HDU 1841:Find the Shortest Common Superstring(KMP)
- HDOJ 1841 Find the Shortest Common Superstring(KMP)
- 题目1841 Find the Shortest Common Superstring(KMP)
- Find the Shortest Common Superstring(hdu1841,KMP)
- hdu1841 Find the Shortest Common Superstring 两遍KMP
- hdu1841 Find the Shortest Common Superstring -- (KMP 前缀,后缀处理)
- hdu1841 Find the Shortest Common Superstring
- hdu 1595 find the longest of the shortest(spfa)(存储并枚举最短路径的边)
- HDU 1595——find the longest of the shortest
- HDU 1595 find the longest of the shortest
- hdu 1595 find the longest of the shortest 最短路dijkstra+枚举