我正在构建一个类似热图的矩形阵列接口,我希望“热”位置位于数组的左上角,而“冷”位置位于右下角。因此,我需要一个像这样对角填充的数组:
0 1 2 3
|----|----|----|----|
0 | 0 | 2 | 5 | 8 |
|----|----|----|----|
1 | 1 | 4 | 7 | 10 |
|----|----|----|----|
2 | 3 | 6 | 9 | 11 |
|----|----|----|----|
实际上,我需要一个函数f(x,y),这样
f(0,0) = 0
f(2,1) = 7
f(1,2) = 6
f(3,2) = 11
(或者,当然,类似函数f(n),其中f(7)= 10,f(9)= 6等)。
答案 0 :(得分:4)
如果您被限制逐行遍历数组,则会出现有趣的问题。 我将矩形划分为三个区域。 左上角三角形,右下角三角形和长菱形。
对于左上角三角形,可以使用通用算术系列1 + 2 + 3 + .. + n = n*(n+1)/2
计算第一列(x = 0)中的值。具有相同x + y值的那个三角形中的字段位于相同的对角线中,并且该值是来自第一个列+ x的总和。
同样的方法适用于右下角三角形。但是,使用x
和y
代替w-x
和h-y
,其中w
是宽度,h
是矩形的高度。必须从数组中的最高值w*h-1
中减去该值。
菱形中间有两种情况。如果矩形的宽度大于(或等于)高度,则矩形的左下角字段是菱形中具有最低值的字段,并且可以计算h-1
之前的总和。从那里你可以想象菱形是一个矩形,其x值为x+y
,y值为y
,来自原始矩形。因此,计算新矩形中的剩余值很容易
在另一种情况下,当高度大于宽度时,可以使用该算术和计算x=w-1
和y=0
处的字段,并且可以将菱形可想象为具有x值{{ 1}}和y值x
。
例如,可以通过预先计算值来优化代码。我认为所有这些案件都有一个公式。也许我以后会考虑它。
y-(w-x-1)
inline static int diagonalvalue(int x, int y, int w, int h) {
if (h > x+y+1 && w > x+y+1) {
// top/left triangle
return ((x+y)*(x+y+1)/2) + x;
} else if (y+x >= h && y+x >= w) {
// bottom/right triangle
return w*h - (((w-x-1)+(h-y-1))*((w-x-1)+(h-y-1)+1)/2) - (w-x-1) - 1;
}
// rhomboid in the middle
if (w >= h) {
return (h*(h+1)/2) + ((x+y+1)-h)*h - y - 1;
}
return (w*(w+1)/2) + ((x+y)-w)*w + x;
}
当然,如果没有这样的限制,那样的事情应该更快:
for (y=0; y<h; y++) {
for (x=0; x<w; x++) {
array[x][y] = diagonalvalue(x,y,w,h);
}
}
答案 1 :(得分:1)
这个怎么样(有一个NxN
矩阵):
count = 1;
for( int k = 0; k < 2*N-1; ++k ) {
int max_i = std::min(k,N-1);
int min_i = std::max(0,k-N+1);
for( int i = max_i, j = min_i; i >= min_i; --i, ++j ) {
M.at(i).at(j) = count++;
}
}
答案 2 :(得分:0)
按照第3个示例中的步骤 - 这给出了索引(为了打印出切片) - 只需使用递增计数器设置值:
int x[3][3];
int n = 3;
int pos = 1;
for (int slice = 0; slice < 2 * n - 1; ++slice) {
int z = slice < n ? 0 : slice - n + 1;
for (int j = z; j <= slice - z; ++j)
x[j][slice - j] = pos++;
}
答案 3 :(得分:0)
在M * N矩阵中,除了边界情况外,当你在所述示例中遍历时,这些值似乎增加了n,所以
f(0,0)=0
f(1,0)=f(0,0)+2
f(2,0)=f(1,0)+3
......依此类推至f(N,0)。然后
f(0,1)=1
f(0,2)=3
然后
f(m,n)=f(m-1,n)+N, where m,n are index variables
和
f(M,N)=f(M-1,N)+2, where M,N are the last indexes of the matrix
这不是决定性的,但它应该给你一些工作。请注意,您只需要每行中前一个元素的值以及几个起始值。
答案 4 :(得分:0)
如果你想要一个简单的函数,你可以使用递归定义。
H = height
def get_point(x,y)
if x == 0
if y == 0
return 0
else
return get_point(y-1,0)+1
end
else
return get_point(x-1,y) + H
end
end
这利用了以下事实:任何值都是H +左侧项目的值。如果该项目已经位于最左侧的列中,那么您将找到位于其最右上角的单元格,并从那里向左移动,并添加1.
这是一个很好的机会使用dynamic programming,“缓存”或记忆你已经完成的功能。
如果您想要f(n)“严格”完成某些事情,您可以使用以下关系:
n = ( n % W , n / H ) [integer division, with no remainder/decimal]
从那里开始工作。
或者,如果你想要一个没有递归的纯数组 - 按行填充方法,你可以遵循以下规则:
Psuedo-Code :(假设数组由arr[row,column]
索引)
arr[0,0] = 0
for R from 0 to H
if R > 0
arr[R,0] = arr[0,R-1] + 1
end
for C from 1 to W
arr[R,C] = arr[R,C-1]
end
end