C++判断一个周期字符串的方法及其拓展

重复的子字符串

问题起源于一道leetcode题目:给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。

该题目的简单解法如下:

class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        return (s + s).find(s, 1) != s.length();
    }
};

该题目实质就是判断一个字符串s是否为周期的,对于一个周期为T的函数,我们有f(x+T)=f(x),所以我们将两个s拼接为一个新字符串,并从这个新字符串的第二个元素即1号元素开始查找s,若s是周期字符串则find()方法返回值必小于新字符串中第二个s开始的位置,这是个充要条件。

字符串的最大公因子

对于字符串 S 和 T,只有在 S = T + … + T(T 与自身连接 1 次或多次)时,我们才认定 “T 能除尽 S”。返回字符串 X,要求满足 X 能除尽 str1 且 X 能除尽 str2。

class Solution {
public:
    string gcdOfStrings(string str1, string str2) {
		if (str1 + str2 != str2 + str1) {
		    return "";
	    }
	    return str1.substr(0, gcd(str1.size(), str2.size()));
    }
    int gcd(int a, int b) {
	    return b == 0 ? a : gcd(b, a % b);
    }
};

这个题目是上一个题目的拓展,在判断字符串是周期的基础上还要找出最小周期,假设s既是str1的最小周期字串也是str2的最小周期字串,则存在正整数m,n使得str1=m×s,str2=n×s,易得str1+str2 == str2+str1是str1与str2有相同周期子串的充要条件。若str1与str2有相同周期子串则需要求出最小周期,即求两个整数的最大公因子问题,使用gcd(辗转相除法)算法即可。

字符串轮转

给定两个字符串s1和s2,编写代码检查s2是否为s1旋转而成(比如,waterbottle是erbottlewat旋转后的字符串)。

class Solution {
public:
    bool isFlipedString(string s1, string s2) {
	    if (s1.size() != s2.size()) {
		    return false;
	    }
	    else if ((s1 + s1).find(s2) != std::string::npos) {
		    return true;
	    }
	    return false;
    }
};

这道题目可以把s1看作周期为s1.size()的字符串,若s2由s1轮转而成,则s1+s1中必然找得到s2,这也是一个充要条件。

原创文章 8 获赞 8 访问量 917

猜你喜欢

转载自blog.csdn.net/I_am_mengxinxin/article/details/104535904