我一直致力于使用强力算法来生成给定集合的所有排列。最后,我想将这些排列中的每一个都输入到nxn矩阵中,以测试它是否是一个有效的魔方。 - 我知道有办法轻松生成魔法广场 - 但这不是我想做的。我专注于它的蛮力方面。
对于一组3个元素,它的工作非常精彩。但是,一旦我使用4个或更多元素,我就会失去一些排列。仅从查看4的输出,我就缺少7种排列。
#include <stdio.h>
#include <iostream>
using namespace std;
//ms = magic square
//n = size
void perm(int ms[], int n) {
int pivot = 0;
int index = 0;
int pivBit = 1;
int fin = 0;
int hold = 0;
//While we are not finished
while (fin == 0) {
//Incriment the index
++index;
if (index >= n) {
index = 0;
}
//if index is equal to the pivot
if (index == pivot) {
//Is this the first time visiting the pivot?
if (pivBit == 0) {
//Are we at the beginning again?
if (index == 0 && pivot == 0)
{
fin = 1;
}
pivBit = 1;
++index;
}
//Second time visiting?
else {
pivBit = 0;
++pivot;
if (pivot >= n) {
pivot = 0;
}
}
}
//If we are out of bounds
if (index >= n) {
index = 0;
}
//swap
hold = ms[index];
ms[index] = ms[pivot];
ms[pivot] = hold;
for (int i = 0; i < n; ++i) {
cout << ms[i];
if (i < n - 1) {
cout << ", ";
}
else {
cout << endl;
}
}
}
}
int main() {
cout << "Are you ready to brute force, my brother?" << endl;
//Set
int magicsquare[] = { 1, 2, 3, 4};
int size = 4;
perm(magicsquare, size);
getchar();
return 0;
}
我的输出是:
2 1 3 4
3 1 2 4
4 1 2 3
1 4 2 3
1 2 4 3
1 3 4 2
3 1 4 2
3 4 1 2
3 4 2 1
2 4 3 1
2 3 4 1
2 3 1 4
4 3 1 2
4 2 1 3
4 2 3 1
1 2 3 4
2 1 3 4
看着它,我已经可以看到我错过了1 4 3 2和1 3 2 4。 我的算法在哪里出错?
答案 0 :(得分:1)
生成所有排列的最简单方法是递归。对于每个i,将第i个元素交换到0位置。然后递归地找到剩余数组的所有排列。
int buf[1000], n; // better to wrap these in a class...
void permute(int *a, int a_len) {
if (a_len == 1) {
for (int i = 0; i < n; i++) printf("%d ", buf[i]);
printf("\n");
} else {
for (int i = 0; i < a_len; i++) {
swap(a, 0, i);
permute(a + 1, a_len - 1);
swap(a, 0, i);
}
}
}
void run(int buf_len) {
for (int i = 0; i < buf_len; i++) buf[i] = i + 1;
n = buf_len;
permute(buf, buf_len);
}
这假设原始数组中没有重复的元素。考虑到重复的因素并不难。
答案 1 :(得分:1)
关于置换的维基文章包括一个常用的算法,用于按字典顺序产生所有排列,从一个顺序递增的整数数组开始,以反转的数组结束。 wiki next permutation
如果处理一个对象数组,你可以生成一个索引0到n-1的数组,并在索引上使用下一个排列来产生对象数组的所有排列。
您还可以对下一个排列进行网络搜索,以查找类似的算法。递归的产生所有排列,但不是按字典顺序排列。