您的位置:首页 > 大数据 > 人工智能

HDU 1867 A + B for you again kmp算法

2016-07-24 15:42 543 查看
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1867

题意:给定两个字符串,把一个字符串接在另一个字符串的后面,相接部位若有相同,则可以略去其中一个字符串的相同部分,输出拼接后最小长度的字符串,若有两种最小长度的字符串,输出字典序较小的那个

思路:可以用kmp匹配一个字符串的尾部和另一个字符串的首部相同的最大长度,然后交换两个字符串的次序,再来一次匹配,根据匹配出来的长度来决定把那个字符串放在前面

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 100010;
int nt
;
char s1
, s2
;

void getnt(char s[])
{
int i = 0, j = -1;
nt[0] = -1;
while(s[i])
{
if(j == -1 || s[i] == s[j])
{
i++, j++;
if(s[i] != s[j]) nt[i] = j;
else nt[i]= nt[j];
}
else j = nt[j];
}
}
int kmp(char s1[], char s2[]) //s1是目标串,s2是模式串
{
getnt(s2);
int i = 0, j = 0;
while(s1[i])
{
if(j == -1 || s1[i] == s2[j])
i++, j++;
else j = nt[j];
if(j != -1 && !s2[j] && s1[i]) //s2匹配到末端时,要判断s1是不是末端,若不是末端,则令j跳转,若是末端,则保持j不变
j = nt[j];
}
return j;
}
int main()
{
while(~ scanf("%s%s", s1, s2))
{
int l1 = kmp(s1, s2); //s1的尾部和s2的首部匹配的长度
int l2 = kmp(s2, s1); //s2的尾部和s1的首部匹配的长度
if(l1 > l2)
{
printf("%s", s1);
printf("%s", s2 + l1);
}
else if(l1 < l2)
{
printf("%s", s2);
printf("%s", s1 + l2);
}
else
{
if(strcmp(s1, s2) < 0)
{
printf("%s", s1);
printf("%s", s2 + l1);
}
else
{
printf("%s", s2);
printf("%s", s1 + l2);
}
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: