您的位置:首页 > 其它

Chapter 1 | Arrays and Strings--旋转字符串的判断

2013-11-30 16:58 417 查看
1.8   Assume you have a method isSubstring which checks if one word is a substring of another. Given two strings, s1 and s2, write code to check if s2 is a rotation of s1 using only one call to isSubstring
(i.e., “waterbottle” is a rotation of “erbottlewat”).

译文:假定你有一个isSubstring函数,可以判断是否一个字符串是另一字符串的字串。给定s1和s2两个字符串,写一个程序只需调用一次isSubstring函数就可以检查是否s2是s1的旋转字符串。示例:"waterbottle"是"erbottlewat"的旋转字符串。

这个题目比较特殊的是你需要调用它给定的一个功能函数isSubstring。而不能直接从字符串s1和s2出发,因为二者并存在子字符串的关系。有另一个思路那就是,不断的旋转s1,然后不断地调用isSubstring来判断是否s1与s2相等,但这违反了题给的条件,只能另辟他路。我们得充分利用给定的isSubstring这个函数的功能,即判定字串关系。旋转字符串就是将字符串循环移位多少位,那就将字符串首尾相连,那么它的旋转字符串肯定在这个环里面,多了个环比较麻烦,且似乎不好利用subString这个函数,我们可以将这个字符串自加,即s1+s1,这样实际也具备环的特点,并且处理起来更加方便。

s1 + s1 = waterbottlewaterbottle;
很明显s1的所有旋转字符串均是s1+s2的字串,这样的话,处理起来就轻松多了。代码如下

bool isRotation(string s1, string s2)
{
int len = s1.length();
if ((s2.length == len) && (len > 0))
{
return isSubstring(s1 + s1, s2);
}
return false;
}


针对旋转字符串和字串也是经常出现的问题,我们这里也稍稍讨论一下。

旋转字符串:偶然间在《编程珠玑》上看到一个关于旋转字符串的题目,具体记不清了,大致是给定一个字符串str,要求得到旋转 i 个位置后的字符串。eg:str = "abcdefg",i = 3,那么得到的字符串为 str = "defgabc"。

这里介绍的是一种采用递归的方法,先翻转前面 i 个字符,然后翻转 i 位置后面的字符,最后再将整个字符串翻转一次,就得到结果了。这个方法很巧妙,不是我想出来的。翻转字符串前面的文章中有讲过,这里就搬过来还需要修改一下,代码如下

void swap(char &a, char &b)
{
if (a != b)
{
a ^= b;
b ^= a;
a ^= b;
}
}

void reverse(string &str, int start, int end)    //字符串中的指定部分start--end翻转
{
while (start < end)
swap(str[start++], str[end--]);
}
那么我们实现的时候就三次调用该翻转函数

reverse(str, 0, i-1);
reverse(str, i, len - 1);
reverse(str, 0, len - 1);
最后得到结果。

子串:估计就会想到kmp字符串匹配算法了,这个算法很巧妙,这里就不花篇幅来讲解了,大家感兴趣就可以参考其余资料
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息