排列 组合
排列
字符串的全排列这种是给你一个序列,让你找出他的全排列,每个位置不重复。(交换)
例如 abc的全排列有 abc, acb, bac, bca, cab, cba
还有一种是每个位置可以重复。(所有可能)
例如 abc的全排列 aaa, aab, aac, aba, abb,abc,....
类似于 输出求n位的每个数 0 ~ 9999....9(n位), 前面的例题。
!!!!对于这种问题,我们把 字符串看成2部分
第一部分 是字符串的第一个字符
第二部分 是字符串的后面的所有字符。
对于交换,先求出第一部分所有可能,再将第一部分的字符和第二部分的所有字符交换。
关于所有可能,先求出第一部分所有可能,和第二部分所有可能。
对于第二部分再递归调用。再看成2部分。
递归函数
/// index 用来监测是否递归到最后了,到最后则输出。
paiLie(char * a, char *index)
{
if('\0' == *index )
cout<< a <<endl; ///到达末尾,可以输出了
else
{
/// (1)交换的话
char tmp, *p;
for(p = index; *p != '\0'; ++p)
{
tmp = *p;
*p = *index;
*index = tmp;
paiLie(a, index + 1);
tmp = *p;
*p = *index;
*index = tmp;
}
///(2)所有可能
int i;
for(i = 0; i < 10; ++i)
{
*p = '0' + i;
paiLie(a, index+1);
}
///(3) 上面是每一位都是0~9的数字,还可以指定每一位的取值范围
/// 这样函数的参数就有需要添加一个base[]
/// paiLie(char * a, char *index, char * base, int baseNum)
int i;
for(i = 0; i < baseNum; ++i)
{
*p = base[i];
paiLie(a, index + 1, base);
}
}
}
/// index 用来监测是否递归到最后了,到最后则输出。
调用该递归函数的话。
main()
{
char a[N+1];
a[N] = '\0';
paiLie(a, a);
}
组合
(2)字符的所有组合例如 abc 的所有组合--- a ,b, c, ab, ac, bc, abc = (2 ^3 -1) 种
对于每一种组合来说,组合数为m , 1<= m <= n;
(1)包括第一个字符, + 不包括第一个字符的m-1个字符的组合
(2)不包括第一个字符 + 不包括第一个字符的m个字符的组合
<span style="font-size:18px;">allZuhe(char * base)
{
int length = strlen(base);
char *result = new char[length + 1];
for(i = 1; i <= length; ++i)
{
allZuhe_recurse(base, 0, result, 0, i);
}
delete[] result;
}
allZuhe_recurse(char *base, int baseIndex,
char *result, int resultIndex, int zuheNum)
{
if(0 == zuheNum)
{
result[resultIndex] = '\0';
cout<<result<<endl;
}
else
{
if('\0' != base[baseIndex])
{
/// 包括第一个字符 + 不包括第一个字符的m-1个字符的组合。
result[resultIndex] = base[baseIndex];
allZuhe_recurse(base, baseIndex+1, result, resultIndex+1, zuheNum-1);
/// 不包括第一个字符 + 不包括第一个字符的m个字符的组合。
allZuhe_recurse(base, baseIndex, result, resultIndex, zuheNum);
}
}
}</span>