问题描述:给定两个字符串s1和s2,要求判定s2是否能够被s1做循环移位得到的字符串包含。例如给定s1=aabcd和s2=cdaa,函数返回true;给定s1=abcd,和s2=acbd返回false。
编程之美上解法二是将问题转化,将原来的字符串扩展。
假设s=abcd,则对s循环移位后得到的结果是:
abcd->bcda->cdab->dabc->abcd。
问题解决的步骤:
假设目标字符串是s,待匹配字符串是d。现在从s的第k个位置开始比较,i表示s的下标,j表示d的下标。
若s[i]==d[j],s和d的下标向前移一位,i=(i+1)mod(len(s)),j=j+1,继续比较。直到d所有字符都匹配了,或是所有情况都不包含d时,匹配失败。
若s[i]!=d[j],s的下标向前移一位,i=(i+1)mod(len(s)),d的下标置0,从头匹配。
与普通字符串匹配不同的是目标字符串S,下标的移动上。在一次匹配中s字符串的结束位置是,当下标i再次回到位置k时。
实现代码:
bool BeautyProgram::ShiftStrSub(const char* src,const char* des)
{
int srclen=strlen(src);
int deslen=strlen(des);
for(int i=0;i<srclen;i++)//从src的第i个位置开始比较
{
for(int j=i;j%srclen!=i||j/srclen==0;j++)//比较的结束位置是下标j再回到起始位置i时,j/srclen==0来判断起始的比较
{
int k=0;
for(int index=j;((index)%srclen!=i||index/srclen==0)&&k<deslen;index++,k++)
{
if(src[(index)%srclen]!=des[k])
{
break;
}
}
if(k==deslen)//匹配成功
return true;
}
}
return false;
}