使用迭代接口的代码。时间复杂度为O(n^2),空间复杂度的开销是:复制n(log n bits),迭代变量(log n bits),跟踪ni(log n bits),复制当前值(记录n比特),p(n记录n比特)的副本,下一个值(记录n比特)的创建以及一组使用值(n比特)的一组比特。您无法避免n个log n位的开销。在时间上,这也是O(n^2),用于设置位。这可以稍微减少一点,但是需要使用装饰树来存储使用的值。
这可以通过调用相应的库来改变为使用任意的精度整数和位集合,而上述边界实际上会启动,而不是在N = 8时被移动(可以移植一个int整数与短小一样,小至16位)。 9! = 362880> 65536 = 2^16
#include <math.h>
#include <stdio.h>
typedef signed char index_t;
typedef unsigned int permutation;
static index_t permutation_next(index_t n, permutation p, index_t value)
{
permutation used = 0;
for (index_t i = 0; i < n; ++i) {
index_t left = n - i;
index_t digit = p % left;
p /= left;
for (index_t j = 0; j <= digit; ++j) {
if (used & (1 << j)) {
digit++;
}
}
used |= (1 << digit);
if (value == -1) {
return digit;
}
if (value == digit) {
value = -1;
}
}
/* value not found */
return -1;
}
static void dump_permutation(index_t n, permutation p)
{
index_t value = -1;
fputs("[", stdout);
value = permutation_next(n, p, value);
while (value != -1) {
printf("%d", value);
value = permutation_next(n, p, value);
if (value != -1) {
fputs(", ", stdout);
}
}
puts("]");
}
static int factorial(int n)
{
int prod = 1;
for (int i = 1; i <= n; ++i) {
prod *= i;
}
return prod;
}
int main(int argc, char **argv)
{
const index_t n = 4;
const permutation max = factorial(n);
for (permutation p = 0; p < max; ++p) {
dump_permutation(n, p);
}
}
你想解决数学问题吗?或者只是一个O(1)(内存)算法来完成这项工作? – 2008-10-02 14:44:37