您链接的代码调用 rpermute0 完成大部分工作,Array.c 中 rpermute0 的源代码是
static void
rpermute0(long n, long r, long *p, long index, VALUE values)
{
long i, j;
for (i = 0; i < n; i++) {
p[index] = i;
if (index < r-1) { /* if not done yet */
rpermute0(n, r, p, index+1, values); /* recurse */
}
else {
/* We have a complete permutation of array indexes */
/* Build a ruby array of the corresponding values */
/* And yield it to the associated block */
VALUE result = rb_ary_new2(r);
VALUE *result_array = RARRAY_PTR(result);
const VALUE *values_array = RARRAY_PTR(values);
for (j = 0; j < r; j++) result_array[j] = values_array[p[j]];
ARY_SET_LEN(result, r);
rb_yield(result);
if (RBASIC(values)->klass) {
rb_raise(rb_eRuntimeError, "repeated permute reentered");
}
}
}
}
基本上是蛮力,从 0 开始,每次迭代返回一个排列。红宝石版本类似于
require 'pp'
def rpermute(numRepeat, pArray, index, originArray)
0.upto(originArray.length-1) do |i|
pArray[index] = i
if index < numRepeat-1
rpermute(numRepeat, pArray, index+1, originArray)
else
result = Array.new
0.upto(numRepeat-1) do |j|
result[j] = originArray[pArray[j]]
end
pp result
end
end
end
originArray1 = [1,2,3,4,5]
originArray2 = ['a','b','c','d','e']
pArray = []
rpermute(4, pArray, 0, originArray1)
rpermute(4, pArray, 0, originArray2)
我测试了上面的代码,它打印出所有长度为 4 的排列,你可能想把它们放入数组中。