将数字映射到 N 维网格/数组
例如,假设我有一个 3 维网格/数组,其中轴从 1 到 1000(或等效的 0 到 999)。该数组有 1000^3 个元素。
我想使用 Java 以确定的方式将 0 到 1000^3 范围内的单个整数映射到该数组。优选地,该解决方案适用于任何维度 N。
这是此类函数的伪代码示例:
public Vector<int> nthElement( Vector<int> dims, int n )
因此,如果我像 nthElement([1000, 1000, 1000], 0)
那样调用它,它将返回 [0, 0, 0]
而 nthElement([1000, 1000, 1000], 1001)
将返回类似 [999, 1, 0]< /代码>。
解决方案应该针对 N 维,而不是像我的示例中那样针对 3 维。
Lets assume, for example, that I have a 3-dimensional grid/array where the axis run from 1 to 1000 (or 0 to 999 equivalently). This array has 1000^3 elements.
I would like to map a single integer in the range 0 to 1000^3 to this array in a deterministic way using Java. Preferably this solution would work for any dimension N.
Here is a pseudo-codish example of such a function:
public Vector<int> nthElement( Vector<int> dims, int n )
So if I would call it like nthElement([1000, 1000, 1000], 0)
it would return [0, 0, 0]
whereas nthElement([1000, 1000, 1000], 1001)
would return something like [999, 1, 0]
.
The solution should be for N dimensions and not for 3 as in my example.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是正确的映射算法:
或递归
其中 A div B 是 Floor(A/B)。
This is the correct mapping algorithm:
or recursive
Where A div B is Floor(A/B).
检查这个
更新
使用示例
将打印
check this
upd
examples of usage
will print
你可以这样做:
这是一个映射(唯一),你可以简单地做反向
注释 2/3 = 0 而不是 .6666
You can do:
It's a mapping (unique), and you can simply do reverse
note 2/3 = 0 not .6666
您可能正在寻找Cantor 配对函数。它是为 NxN 定义的,因此您可以将其用于任意大的尺寸。正如维基百科页面上提到的,它可以归纳推广到维度为 n 的数组,在您的情况下 n=3 工作得很好。
上面的页面还解释了函数的反转,这样您就可以从给定的数字获取数组中的坐标,这正是您想要的
nthElement
。当然,康托只定义了一种穿过二维场的可能方法。还有其他可能的步行方式,但这是最受欢迎的方式。
编辑:我应该提到,如果你的数组具有矩形尺寸,康托配对函数将假定最大类型的尺寸。因此关联的数字不再连续出现在数组中。 F. 前。大小为 1000x2 的数组将被视为 1000x1000 数组,并且与实际数组中的条目对应的数字将只是数字 0..1000*1000 的非连续列表。
然而,如果你的三个维度始终相同,那么这一点可以完全忽略。
回应评论:逐行配对和康托配对只是遍历矩阵空间的不同方式。康托配对的一个优点是它是在自然数上定义的,因此如果您没有矩阵维度的精确值,或者您的矩阵随着时间的推移而增长,它也适用。
What you are probably looking for is the Cantor pairing function. It is defined for NxN, so you can use it for arbitrarily large dimensions. As mentioned on the wikipedia page it can be inductively generalized to an array of dimension n, in your case n=3 works just fine.
The above page also explains inverting the function, so you can get your coordinates in the array from the given number, which is exactly what you want with
nthElement
.Of course, Cantor has only defined one possible way to walk through a two-dimensional field. There are other possible walks, but this one is the most popular way to do it.
Edit: I should mention, that if your array has rectangular dimensions the Cantor pairing function would assume dimensions of the largest kind. So the associated numbers are no longer successively within your array. F.ex. an array of size 1000x2 would be treated as a 1000x1000 array and the numbers corresponding to entries in your actual array would only be a non-successive list of the numbers 0..1000*1000.
If, however, your three dimensions are always the same, then this point can be totally ignored.
In response to the comment: Row-by-row and Cantor pairing are just different ways to walk through your matrix space. An advantage of Cantor pairing is that it is defined over the natural numbers and hence also is applicable if you do not have exact values for your matrix dimensions, or your matrix grows over time.