蛮力置换交换
Brute Force Permutation Swapping
本文关键字:交换 更新时间:2023-10-16
我一直在研究一种暴力算法来生成给定集合的所有排列。最后,我想把这些排列中的每一个都输入到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。我的算法哪里出了问题?
关于排列的wiki文章包括一个常用算法,用于按字典顺序生成所有排列,从一个按顺序递增的整数数组开始,到该数组反转结束。wiki下一个排列。
如果处理对象数组,可以生成索引0到n-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);
}
这假定原始数组中没有重复的元素。让它考虑重复的元素并不难。
相关文章:
- C++嵌套if语句,基本货币交换
- shell排序中的交换和比较
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- 通过交换元素使数组相同
- 如何使 std::sort 在 std::swap 和我的命名空间的模板化交换之间没有名称冲突?
- 交换运算符 + 重载会导致无限递归
- 为什么 std::reduce 需要交换性?
- 复制和交换习惯用法与移动操作之间的交互
- C++ - 没有自定义交换功能的移动分配运算符?
- 如何在数组中交换最小和最大的位置?
- 尽管一切看起来都很好,但值不会交换
- C++交换来自同一类成员的参数值,处理多个类
- 插入排序的最小交换
- C++在 2 个向量向量之间交换向量
- 转置矩阵:交换元素不会更改值
- 不正确的比较和交换计数器输出用于快速排序功能
- 交换函数不是在 C++ 中交换 2D 数组的元素
- std::vector move 而不是交换到空 vector 并释放存储
- 否,除了交换和移动具有互斥锁的类
- 如何交换数组中的元素?