给出一个非空的字符串,判断这个字符串是否是由它的一个子串进行多次首尾拼接构成的。
例如,"abcabcabc"满足条件,因为它是由"abc"首尾拼接而成的,而"abcab"则不满足条件。
输入描述:
非空字符串
输出描述:
如果字符串满足上述条件,则输出最长的满足条件的的子串;如果不满足条件,则输出false。
示例1
输入
abcabc
输出
abc
思路:
由题意可知,我们不能把整个字符串看成一个子串。因为“拼接”至少需要2个字符串,最多可以有整个字符串的size()大小。
所以有:
1.对子串个数进行遍历,从2个到字符串的size();
2.因为子串的个数和子串的长度都是整数,所以我们要挑选合法的情况,即子串个数可以被整个字符串整除的;
3.计算每个子串的长度;
4.取出第一个子串;
5.比较第一个子串和后续子串是否相等,如果不相等,则直接break;如果相等,则比较下一个第一个子串和后续下一个子串;
6.判断是因为走完了整个for循环还是因为中途break的情况。如果是走完整个for循环,则说明整个字符串是由第一个子串拼接而成,并返回这个子串;否则说明该子串并不是有第一个子串拼接而成,并返回空字符串(即“”)。
代码:
#include <iostream>
#include <string>
using namespace std;
string process(const string &str){
for (int i = 2; i <= str.size(); i++){ //遍历段数,切成i段
if (str.size() % i == 0){
int subLen = str.size() / i; //每个子串长度
string subStr = str.substr(0, subLen);
int j = 0;
for ( j = subLen; j < str.size();j+=subLen){ //从第二个子串开始
if (subStr != str.substr(j, subLen)){
break;
}
}
// cout << str.size()<<endl;
if (j >= str.size()){
return subStr;
}
}
}
return "";
}
int main(){
string str;
while (cin >>str)
{
string res = process(str);
if (res.size()<1)
{
cout << "false" << endl;
}
else{
cout << res << endl;
}
}
return 0;
}