如何编写算法来查找给定点的所有对角点?
如:
00 01 02 03 04 05
10 11 12 13 14 15
20 21 22 23 24 25
30 31 32 33 34 35
40 41 42 43 44 45
50 51 52 53 54 55
当选择点34时,如何找到相邻的对角点? (01,12,23,45,25,43,52)
00(01)02 03 04 05
10 11(12)13 14 15
20 21 22(23)24(25)
30 31 32 33 X 35
40 41 42(43)44(45)
50 51(52)53 54 55
由于我没有说明我使用的编程语言,我更喜欢伪代码或指令。
Ps:我不想直接代码赠品,因为我正在尝试通过遵循伪代码或说明来学习代码。
答案 0 :(得分:3)
让我们说你的观点是(a,b)。如果存在i
整数,则给定(c,d)点位于同一对角线上,以便
a + i = c且b + i = d 或强> a + i = c和b - i = d
由于距离为i
,您可以执行以下操作:
for i <- 0, n - 1
if i <> a then
if (b - i) >= 0 and (b - i) < n then (i, b - i) is on the diagonal
if (b + i) >= 0 and (b + i) < n then (i, b + i) is on the diagonal
end if
end for
答案 1 :(得分:1)
暴力解决方案
在整个网格上写一些简单的for循环。对角线上的任何点都有一个斜率为起点
假设零索引N x N框,x从左到右增加,y从上到下增加
values = list()
location = (3,4)
for y in 0 ..N-1:
for x in 0..N-1:
if (x, y) == location:
continue
slope = abs(y-location(0))/abs(x-location(1))
if slope == 1:
list.add( (y, x) )
更优化的解决方案
从位置坐标开始,然后向外扇出,同时增加和/或减少x,y点。该方法的棘手部分是当一个方向碰到边界时不破坏循环
答案 2 :(得分:1)
我用C#为此接受的答案(https://stackoverflow.com/a/45896595/1566372)编写了一个实现
public IEnumerable<(int i, int j)> GetDiagonalPoints(int a, int b, int n)
{
/*
for i <- 0, n - 1
if i <> a then
dist = Abs(i - a)
if (b - dist) >= 0 and (b - dist) < n then (i, b - dist) is on the diagonal
if (b + dist) >= 0 and (b + dist) < n then (i, b + dist) is on the diagonal
end if
end for
*/
for (int i = 0; i < n; i++)
{
if (i != a)
{
var dist = Math.Abs(i - a);
if ((b - dist) >= 0 && (b - dist) < n) yield return (i, b - dist);
if ((b + dist) < n) yield return (i, b + dist);
}
}
}
答案 3 :(得分:0)
我更容易编写代码本身而不是伪代码......
N是从零开始的矩阵的大小。
public static void diagonal(int N, int x, int y) {
int max = Collections.max(Arrays.asList(x, y, N - x, N - y));
for (int i = 1; i < max; i++) {
addIfValid(N, x + i, y + i);
addIfValid(N, x + i, y - i);
addIfValid(N, x - i, y + i);
addIfValid(N, x - i, y - i);
}
}
private static void addIfValid(int N, int i, int j) {
if (i >= 0 && i < N && j >= 0 && j < N) {
// collect the results in a list or process them in any way
System.out.println(i + ":" + j);
}
}
答案 4 :(得分:0)
在Lajos Arpad回答的指导下,我做了一些改变以满足我的需求。
//point_given = (3,3)
//matrix = 5*4
/*
00 01 02 03
10 11 12 13
20 21 22 23
30 31 32 33
40 41 42 43
*/
x = 3 // x of given point
y = 3 // y of given point
N = 5 //row
M = 4 //col
//use row to iterate only
for i = 0 to N, i+1
//no diagonal point on same row of given point
if i <> x
//to check if y in bound of matrix col for the left and right diagonal
//used abs(x-i) to know how much value to add to y col
//e.g. 1 row up of x means the diagonal point y is 1 col left and 1 col right to given y
if((y-abs(x-i))>=0) then (i,y-abs(x-i)) is a diagonal point on left
endif
if((y+abs(x-i))<M) then (i,y+abs(x-i)) is a diagonal point on right
endif
endif
endfor