从维值列表中创建n维矩阵

时间:2015-03-22 23:13:58

标签: arrays matrix

我需要创建一个n维矩阵,其中包含来自任意大小的数组列表的所有可能的项目组合,以通用的方式处理“维度”列表和每个值中的值的任意大小尺寸。

例如,假设我的程序输入了这个输入:

type: d4, d6, d8, d12, d20
color: red, blue, golden

然后我需要生成以下项目列表:

red d4, red d6, red d8, red d12, red d20, blue d6, blue d8, blue d12, blue d20,
golden d4, golden d6, golden d8, golden d12, golden d20

我最初有一个适用于二维的静态代码,但现在我需要解决1~n维。

任何标准编程语言都可以(即请不要使用神奇的函数式语言,我不知道如何翻译成我的实现),甚至是免费的语言描述。非常感谢。

2 个答案:

答案 0 :(得分:2)

这类似于增加数字的方式。例如,十进制数具有单位,数十,数百。现在说你的单位是类型,你的数十是你的颜色......但是每个数字可能有不同数量的值。

所以我们将d4映射到0,d6映射到1,d8映射到2,d12到3,d20到4.我们将红色映射为0,蓝色映射为1,金色映射为2.让我们开始计数:

00 => (d4, red)
01 => (d6, red)
02 => (d8, red)
03 => (d12, red)
04 => (d20, red)
10 => (d4, blue)
11 => (d6, blue)
...

因此算法会增加第一个数字,除非它达到最大值,在这种情况下我们将其设为零,然后我们增加第二个数字。如果在递增第二个数字时,它已经是最大值,那么我们将其设为零,然后我们继续到第三个数字......

这是python代码:

d = [
    ["d4", "d6", "d8", "d12", "d20"],
    ["red", "blue", "golden"]
]

n = len(d)  # n is number of dimensions
s = [0] * n  # Start with zeroes for each dimension
flag = True
while flag:
    # print tuple
    print ",".join(d[dimension][index] for dimension, index in enumerate(s))
    for dimension in xrange(n):
        s[dimension] += 1  # Increment dimension

        # Have we exchausted dimension values?
        if s[dimension] == len(d[dimension]):
            s[dimension] = 0  # Make 0 and move to next dimension
            flag = dimension < n - 1  # Have we exchausted all dimensions?
        else:
            break

输出:

4,red
d6,red
d8,red
d12,red
d20,red
d4,blue
...
d12,golden
d20,golden

答案 1 :(得分:1)

使用递归深度来处理n(数组数组的长度)。

sub sample {
    my $a = pop;
    return @_
      ? map {
        my $i = $_;
        map { [ @$i, $_ ] } @$a
      } sample(@_)
      : map { [$_] } @$a;
}
@aoa = ( [qw/i j k l m/], [qw/ a s d f g/], [ 1, 2, 3, 4 ], [ 7, 3 ] );
use Data::Dumper;
@pk = sample(@aoa);
print Dumper \@pk;
print scalar @pk;

Python代码:

def sample(aoa):
    a = aoa.pop()
    return [[i] for i in a ] if len(aoa) == 0 else [ i+[j] for i in sample(aoa) for j in a]

#demo
aoa_in = [
       ["i", "j", "k", "l", " m"],
       ["a", "s", "d", "f", "g"],
       [ 1, 2, 3, 4 ],
       [ 7, 3 ]
      ]
import pprint
pp= pprint.PrettyPrinter(indent=2)
pp.pprint(sample(aoa_in))