版权声明:转载请注明出处https://blog.csdn.net/hhmy77 https://blog.csdn.net/hhmy77/article/details/88694473
一道填空题,不考虑时间复杂度。
我一开始想的是可以每找到一个原生字符串(即可以生成所有其它字符串的字典序最小字符串),然后循环生成每个它的子字符串一起存到vector中,每次碰到新的查找即可。但是我没想到怎么找到这个所谓的原生字符串,想过压缩字符串来存储,但是还是没有实现。
上网搜了一下题解 发现每找到一个新的字符串,把它扩大两倍,它的所有子串都能在这个两倍的字符串中找到。
比如
abc
cab
bca
把上述串首尾相连 abcabbca 然后压缩相同字符就变成了
abcabc
而且一个串能循环生成的串数量是该串的长度
还有需要注意的是一个串和一个串的翻转并不相同,所以我们还要存储翻转后的串
上述那个扩大两倍我确实没想到,确实能验证这样做是正确的,但是这样做的依据是什么的?
#include<bits/stdc++.h>
using namespace std;
//a 3 b 4 c 5
//全选然后问有多少组合 可以转动(循环) 翻转 即aaabbbbccccc=caaabbbcccc
//由一个初始的序列 生成所有的序列
//因为可以转动手链 可以把字符串乘2可以在这个大字符串中就可以查找到所有的生成情况! 一般来说可以生成的情况是串的两倍
//需要注意的是 手链和反转后的手链并不相同,
//如 a3b4c5 翻转后 c5b4a3 两个是不同的
int ans=0;
int main()
{
vector<string>vts;
int ans=0;
string str="aaabbbbccccc";
do
{
bool ok=true;
for(int i=0;i<vts.size();i++)
{
if(vts[i].find(str)!=string::npos)
{
ok=false;
break;
}
}
if(ok)
{
string tmp=str;
vts.push_back(tmp+tmp);
reverse(tmp.begin(),tmp.end());
vts.push_back(tmp+tmp);
ans++;
}
}while(next_permutation(str.begin(),str.end()));
cout<<ans;
}