【发布时间】:2018-05-17 08:29:51
【问题描述】:
多线性映射 M 的元素存储在长度为 N 的一维数组中,形状 S 由 S:[Int] = [p,q,r,...] 定义,因此 q*p*r*... = N。 Shape 的大小是可变的,在编译时是未知的。
我要解决的问题是使用整数数组访问地图元素的通用方法,其中各个值是形状 S 中的坐标,例如:M[1,3,2], M[2,3,3,3] 等...这是一个不同的问题来自地图元素的简单枚举。
一种方法是使用M[i,j,k] 并实现下标方法。不幸的是,这种方法对地图的形状进行了硬编码,算法不再是通用的。
假设有一个实用函数从映射的 Shape 派生的元组返回元素索引,因此:
func index(_ indexes:[Int]) -> Int {....}
func elementAt(indexes:[Int]) -> Element {
return elements_of_the_map[self.index(indexes)]
}
M.elementAt(indexes:[i,j,k]) or M.elementAt(indexes:[i,j,k,l,m]) 始终有效。所以此时的问题是构建数组[i,j,k,...]
问题:有没有一种算法可以有效地枚举这些索引?嵌套循环不起作用,因为在编译时不知道循环的数量,并且递归函数似乎增加了很多复杂性(特别是跟踪以前的索引)。
我正在考虑一种算法'a la' base-x 计数,即在右上角的索引中添加一个单位,如果计数超过地图形状的元素数量,则向左移动一个单位。
【问题讨论】:
-
给定一个形状(例如 [3, 2, 2]),您要枚举所有可能的索引 [0, 0, 0], [0, 0, 1], [0, 1, 0 ], ... [2, 1, 1] ?
-
是的。但请注意,在编译时形状是未知的。
-
注意:我很快测试了一个计算 'a la' base-x 的算法,虽然很笨重,但似乎可以工作。
-
对于每个元素索引(在
0..<N范围内)你可以计算相应的索引数组,是你做的吗? -
IMO 不可能从
0..<N范围内的索引计算索引数组,因为对于一个给定的整数,可能有多种分解。我所做的是“如何以从右到左的方式将一个'单位'添加到 [1,1,2],限制为 [2,2,3]?也就是说,如果最右边的索引超过 2,则将其变为 0,然后移动到下一个。