题目:将一个字符串进行排列组合。例:"abc" 总共6中排列组合。
1. a开头的,后面紧跟bc的组合,2种
2. b开头的,后面紧跟ac的组合,2种
3. c开头的,后面紧跟ab的组合,2种
(1)直接设计算法如下:
// array 为原序列,index为下标(以某字符开头的索引), end为原序列最后一个字符的下标(用以上界for遍历)
void Permutations(int *array, const int index, const int end)
{
// a开头, bc所有排列组合
swap(array[0],array[0]; //把a置于开头
Permutations(array, index+1, len);
swap(array[0],array[0]; //还原序列
// b开头,ac所有排列组合
swap(array[0],array[1]; //把b置于开头
Permutations(array, index+1, end);
swap(array[0],array[1]; //还原序列
// c开头,ab所有排列组合
swap(array[0],array[2]; //把b置于开头
Permutations(array, index+1, end);
swap(array[0],array[2]; //还原序列
}
(2)那么,把三个重复的地方改为for循环,使得代码更加简洁,并通用任意长度字符串
// array 为原序列,index为下标(以某字符开头的索引), end为原序列最后一个字符的下标(用以上界for遍历)
void Permutations(int *array, const int index, const int end)
{
for (int i = index; i < end; i++ )
{
swap(array[0],array[index]; //把index位置的字符置于开头
Permutations(array, index+1, end);
swap(array[0],array[index]; //还原序列
}
}
(3)以上递归实现了排列组合,那么递归需要终止条件。即:index == end (所有开头的情况均已列举完毕)
// array 为原序列,index为下标(以某字符开头的索引), end为原序列最后一个字符的下标(用以上界for遍历)
void Permutations(char *array, const int index, const int end)
{
if (index == end)
{
for (int i = 0; i <= end; i++)
{
cout << array[i];
}
cout << endl;
return;
}
for (int i = index; i <= end; i++)
{
swap(array[index],array[i]); //把index位置的字符置于开头
Permutations(array, index+1, end);
swap(array[index],array[i]); //还原序列
}
}
(4)完整程序
#include
#include
using namespace std;
// array 为原序列,index为下标(以某字符开头的索引), end为原序列最后一个字符的下标(用以上界for遍历)
void Permutations(char *array, const int index, const int end)
{
if (index == end)
{
for (int i = 0; i <= end; i++)
{
cout << array[i];
}
cout << endl;
return;
}
for (int i = index; i <= end; i++)
{
swap(array[index],array[i]); //把index位置的字符置于开头
Permutations(array, index+1, end);
swap(array[index],array[i]); //还原序列
}
}
int main()
{
char a[] = "abc";
Permutations(a,0,2);
return 0;
}
结果: