7、排列组合
先封装一个函数:
void Permutations(char* num, const int Findex, const int Lindex) // Findex/Lindex = 开始下标/结束下标
{
/// 假设又有一个 char num = "abc";
// a开头,后面是bc的所有排列
swap(p[0], p[0]); // a和a自己进行交换 1
Permutations(p, 1, 2); // 递归调用自己 2
swap(p[0], p[0]); // 再换回来,换回abc 3
// b开头,后面是ac的所有排列
swap(p[0], p[1]) // a和b交换位置, 就成了b开头 bac 1
Permutations(p, 1, 2); // 递归调用自己 2
swap(p[0], p[1]); // 再交换回来,换回abc 3
// c开头,后面是ab的所有排列
swap(p[0], p[2]); // a和c交换位置,就成了c开头 cab 1
Permutations(p, 1, 2); // 递归调用自己 2
swap(p[0], p[2]); // 再换回来,换回abc 3
}
这样写可以帮助理解工作原理。理解了之后,可以发现重复步骤较多,可以升级成一个for循环:
void Permutations(char* num, const int Findex, const int Lindex) // Findex/Lindex = 开始下标/结束下标
{ // 结束条件
if (Findex == Lindex)
{
//结束了就把最后的结果打印出来
for (int i = 0; i <= Lindex; i++)
{
cout << num[i] << '\t';
}
cout << endl;
}
else
{
for (int i = Findex; i <= Lindex; i++)
{ // Findex就是开头元素的下标0,是不变的,i则是变化的
swap(num[Findex], num[i]); // 这一步就是把上个写法的标记为1的步骤替换掉。
// Findex + 1 就相当于 a开头,换成b开头,因为a开头的abc已经是确定了的,不需要排列。
Permutations(num, Findex + 1, index); // 替换上个写法标记为2的步骤。
swap(num[Findex], num[i]); // 替换上个写法标记为3的步骤。
}
}
}
这样函数就写好了,可以调用试试看:
int main()
{
char num[] = "abc";
char num2[] = "abcdefg";
Permutations(num, 0, 2);
Permutations(num2, 0, 6);
return 0;
}