前面已经提到过全排列,但那个并不足以应对有重复元素的序列,所以现在补上!
怎么操作呢?很简单,只需要在上一节全排列的基础上加上一个检测前后元素是否ok的函数即可。
如果要交换的元素是相等,则返回不可以交换的指示,如此即可完美的解决该问题~
#include <iostream>
using namespace std;
/************ 有重复元素的全排列问题 ******************/
//函数声明
void Perm(int* nums, int begin, int end);
bool canSwap(int* nums, int begin, int end);
void Swap(int& a, int& b);
void printArray(int* nums, int length);
//函数声明
/************ 全排列算法如下 ******************/
void Perm(int* nums, int begin, int end) {
if (begin == end - 1) printArray(nums, end);
else {
for (int i = begin; i < end; i++) {
if (canSwap(nums, begin, i)) {
Swap(nums[begin], nums[i]);
Perm(nums, begin + 1, end);
Swap(nums[begin], nums[i]);
}
}
}
}
/************ main函数如下 ******************/
int main() {
/*题1 有重复元素的全排列*/
int nums[] = { 1, 1, 2, 2 };
int length = sizeof(nums) / 4;
Perm(nums, 0, length);
system("pause");
return 0;
}
/*测试案例;1 1 2 2
【 1 1 2 2 】
【 1 2 1 2 】
【 1 2 2 1 】
【 2 1 1 2 】
【 2 1 2 1 】
【 2 2 1 1 】
*/
/************ 工具类函数如下 ******************/
void printArray(int* nums, int length) {
cout << "【 ";
for (int i = 0; i < length; i++) {
cout << nums[i] << " ";
}
cout << "】" << endl;
}
void Swap(int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
}
bool canSwap(int* nums, int begin, int end) {
for (int i = begin; i < end; i++) {
if (nums[i] == nums[end]) {
return false;
}
}
return true;
}