我尝试生成长度为n
的所有字符串,以便字符串4
的长度为w
的所有子字符串都出现,而所有三个字母a, b, c
都会出现。例如,abbcaabca
时应打印n = 9
,但不应包含aabbcabac
。
现在我只打印所有排列,但我不知道如何只打印这种语言的排列。
void swap(char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
void permute(char *a, int l, int r)
{
int i;
if (l == r)
printf("%s\n", a);
else
{
for (i = l; i <= r; i++)
{
swap((a+l), (a+i));
permute(a, l+1, r);
swap((a+l), (a+i));
}
}
}
int main(){
int n;
cout << "Enter n: " << endl;
cin >> n;
char str[] = "abc";
int x = n % 3;
if (x != 0){
for (int i = 0; i < x; i++)
*str = *str + str[i];
}
permute(str, 0, n - 1);
return 0;
}
答案 0 :(得分:0)
这个解决方案怎么样?
#include <set>
#include <string>
#include <iostream>
void genStrList (std::set<std::string> & setStr,
std::size_t const len,
std::string const & nowStr,
std::string const & poolCh)
{
int i;
std::set<char> noLast3;
std::string::const_reverse_iterator cri;
std::string::const_iterator ci;
if ( 2U < nowStr.size() )
{
for ( ci = poolCh.begin() ; ci != poolCh.end() ; ++ci )
noLast3.insert(*ci);
for ( cri = nowStr.rbegin(), i = 0 ; i < 3 ; ++cri, ++i )
noLast3.erase(*cri);
}
if ( 2U > noLast3.size() )
{
for ( ci = poolCh.begin() ; ci != poolCh.end() ; ++ci )
if ( noLast3.empty() || (noLast3.end() != noLast3.find(*ci)) )
{
if ( nowStr.size() + 1U == len )
setStr.insert(nowStr+(*ci));
else
genStrList(setStr, len, nowStr+(*ci), poolCh);
}
}
}
int main()
{
std::size_t n;
std::cout << "Enter n: " << std::endl;
std::cin >> n;
std::set<std::string> setStr;
genStrList(setStr, n, "", "abc");
std::set<std::string>::const_iterator ci;
for ( ci = setStr.begin() ; ci != setStr.end() ; ++ci )
std::cout << "- " << (*ci) << '\n';
return 0;
}
答案 1 :(得分:0)
一个明显的解决方案是增加块
scope=openid%20profile
以便它检查字符串/* ... */
if (l == r)
printf("%s\n", a);
/* ... */
是否满足条件,即,过去四个字符(a
)中的每个索引3 <= i < n
是否都满足条件{{1} },a[i-3], ..., a[i]
和a
发生。这可以在b
时轻松完成(其中c
是字符串O(n)
的长度)。总体运行时间从n
增加到a
。
一个更“聪明”的解决方案是运行簿记 - 一个你在每次递归调用中修改的全局变量 - 这样你就可以提前修剪坏分支(即你不进行进一步的递归调用如果字符串的开头违反了条件)。在这种情况下,运行时间为O(n!)
(即渐近地快于O(n!*n)
;请参阅little-o notation)。