终曲(hdu 2572)解题报告
Problem Description
最后的挑战终于到了!
站在yifenfei和MM面前的只剩下邪恶的大魔王lemon一人了!战胜他,yifenfei就能顺利救出MM。
Yifenfei和魔王lemon的挑战很简单:由lemon给出三个字符串,然后要yifenfei说出第一串的某个子串,要求该子串长度最小,并且同时包含第2个串和第3个串。
特别地,如果有多个这样的子串,则请输出字母序最小的一个。
Input
输入数据首先是一个整数C,表示测试数据有C组;
接着是C组数据,每组包含三行字符串,第一个字符串长度大于1小于100
后面两个串的长度大于1且小于10
Output
请对应每组输入数据输出满足条件的最短子串;
如果没有,请输出 No
Sample Input
2
abcd
ab
bc
abc
ab
bd
Sample Output
abc
No
思路:
因为str2和str3的长度小于等于10,所以求str1中包含str2和str3的子串就直接用strstr函数了。
下面看一个例子
Str1:abdedbcabcde
Str2:ab
Str3:bc
a | b | d | e | d | b | c | a | b | c | d | e |
↑p | |||||||||||
↑q |
设p为Str2在Str1中出现的位置指针,而q为str3在Str1中出现的位置指针。
用strstr可分别求出p,q的初始值。p&&q为0说明不存在这样的子串。
比较p,q的大小可确定子串的内容。
如上表该子串为:”abdedbc” 即头元素的位置为p,长度为 q-p+strlen(str3)。
因p<q,所以继续查找str2在str1中出现的下一个位置。
直到p或者q为null。
好了找到所有满足条件的子串没有,现在问题的关键是要找出所有最短的子串。最简单的方法就是保存所有满足条件的子串,然后按长度排序。这里要注意的是当长度相同的时候,要按字典序比较字符串。
结论:用strstr求出满足条件的子串,然后用set容器找出最短子串。
代码:
#include <string>
#include <iostream>
#include <string.h>
#include <set>
using namespace std;
struct comp
{
bool operator()(const string &a ,const string & b)
{
if(a.length()==b.length())
return a.compare(b);
return a.length()<b.length();
}
};
int main()
{
int n,l1,l2,l3;
char s1[101],s2[11],s3[11],st[101],*p,*q;
set <string,comp>an;
string ss;
cin>> n;
while (n--)
{
cin >> s1>>s2>>s3;
l1=strlen(s1);
l2=strlen(s2);
l3=strlen(s3);
p=q=s1;
p=strstr(p,s2);
q=strstr(q,s3);
if(p && q)
{
while(p && q)
{
if(p<q)
{
strncpy(st,p,q-p+l3);
st[q-p+l3]='\0';
p=strstr(p+1,s2);
}
else
{
strncpy(st,q,p-q+l2);
st[p-q+l2]='\0';
q=strstr(q+1,s3);
}
ss=st;
an.insert(ss);
}
cout << *an.begin() << endl;
}
else
cout << "No" << endl;
an.clear();
}
return 0;
}
个人网站:生活百科
本文版权所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。