使用迭代接口的代碼。時間複雜度爲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