0
点赞
收藏
分享

微信扫一扫

hdu 1867 求两个串的

Gaaidou 2022-07-27 阅读 97

题意:
      给你两个字符串,让你求str1+str2,就是把1的后面和2的前面重叠的地方只显示一遍就行了 abc + bcd = abcd,要求和的长度最小,和最小的前提下求字典序最小,还有就是两个串可以交换位置的,cdab + abcd = abcdab 而不是 cdabcd,交换位置后合并是最短并且字典序最小的。



思路:
      首先得到两个next数组,然后用str1 去匹配 str2,再用str2 去匹配str1,(因为可以交换),分别得到子串走到最后时匹配串的位置,x,y,这个位置也就是重合了多少个,如果x == y说明无论谁在前前面,匹配后的长度都是 l1 + l2 - x(或者 l1 + l2 - y ,x 和 y是相等的),这样我们把字典序小的那个放在前面,另一个把前面的x个字母去掉后接到字典序小的那个串的后面。如果x != y,如果x > y 当然是按照大的那个匹配方式输出了。因为要求的是和的长度最小。

 

#include<stdio.h>

#include<string.h>#define N 100000 + 100
int next_a[N] ,next_b[N];

char str_a[N] ,str_b[N];void get_next(char str[] ,int next[])

{

int j ,k ,m;

m = strlen(str);

j = 0 ,k = -1;

next[0] = -1;

while(j < m)

{

if(k == -1 || str[j] == str[k])

next[++j] = ++k;

else

k = next[k];

}

return;

}



int KMP(char str1[] ,char str2[] ,int next[])

{

int n ,m ,i ,j;

n = strlen(str1);

m = strlen(str2);

for(i = j = 0 ;i < n ;)

{

if(str1[i] == str2[j])

{

i ++ ,j ++;

}

else

{

j = next[j];

if(j == -1)

{

j = 0;

i ++;

}

}

}

return j;

}int main ()

{

while(~scanf("%s %s" ,str_a ,str_b))

{

get_next(str_a ,next_a);

get_next(str_b ,next_b);

int x = KMP(str_a ,str_b ,next_b);

int y = KMP(str_b ,str_a ,next_a);

if(x == y)

{

if(strcmp(str_a ,str_b) <= 0)

printf("%s%s\n" ,str_a ,str_b + x);

else

printf("%s%s\n" ,str_b ,str_a + x);

}

else

{

if(x > y)

printf("%s%s\n" ,str_a ,str_b + x);

else

printf("%s%s\n" ,str_b ,str_a + y);

}

}

return 0;

}



举报

相关推荐

0 条评论