如何排除超出矩阵范围的坐标。

huangapple go评论86阅读模式
英文:

How to exclude coordinates which overflow matrix

问题

任务是编写一个函数,该函数返回一个元素的所有邻居。对角线上的元素不被视为邻居。

一般情况下,问题已经解决,但如果元素超出了矩阵范围,编译器会生成运行时错误:索引超出范围[-1]。现在我正在考虑添加一个条件来排除矩阵外的数据。你能告诉我这样的条件应该是什么样子的吗?我已经尝试过类似这样的条件:如果元素等于-1,则从响应中删除元素。但它不起作用。

package main

import "fmt"

func Input(y, x int) []int {
    matrix := [][]int{
        []int{0, 2, 3},
        []int{2, 3, 1},
        []int{8, 7, 4},
        []int{3, 2, 1},
    }
    k := []int{matrix[y+1][x], matrix[y-1][x], matrix[y][x+1], matrix[y][x-1]}
    for _, z := range k {
        if z == -1 { //error
            return append(k[z:], k[:z-1]...)
        }
    }
    return k
}
func main() {
    fmt.Println(Input(0, 0))
}

请提供翻译后的代码部分。

英文:

The task is to write a function that returns all its neighbors for an element. Diagonal elements are not considered neighbors.

In general, the problem is solved, but if the elements fall outside the matrix, the compiler generates runtime error: index out of range [-1] . Now I'm thinking of making a condition that excludes data outside the matrix. Can you tell me how such a condition would look like? I've already tried something like: if element = -1, then remove element from response. But it doesn't work.

package main

import "fmt"

func Input(y, x int) []int {
    matrix := [][]int{
        []int{0, 2, 3},
        []int{2, 3, 1},
        []int{8, 7, 4},
        []int{3, 2, 1},
    }
    k := []int{matrix[y+1][x], matrix[y-1][x], matrix[y][x+1], matrix[y][x-1]}
    for _, z := range k {
        if z == -1 { //error
            return append(k[z:], k[:z-1]...)
        }
    }
    return k
}
func main() {
    fmt.Println(Input(0, 0))
}

答案1

得分: 1

xy的索引都可能超出范围,不仅仅是当它们为-1时,还包括它们大于等于你用它们进行索引的切片的长度。

所以基本上有4个邻居:

(y-1,x), (y+1, x), (y,x-1), (y,x+1)

你必须检查所有越界的情况。你的panic发生在k := ...这一行,而不是在for循环内部。同时,在循环中提前返回将无法处理所有元素,并且该for循环从根本上就是错误的。

所以基本上你可以这样做:

var result []int

if y > 0 {
	result = append(result, matrix[y-1][x])
}
if y < len(matrix)-1 {
	result = append(result, matrix[y+1][x])
}
if x > 0 {
	result = append(result, matrix[y][x-1])
}
if x < len(matrix[y])-1 {
	result = append(result, matrix[y][x+1])
}

return result

这将输出(在Go Playground上尝试):

[2 2]

请注意,如果xy已经无效,上述代码仍然会引发panic。如果你想防止这种情况发生,你还必须验证xy,例如:

var result []int
if y < 0 || y >= len(matrix) || x < 0 || x >= len(matrix[y]) {
	return result
}

另一种方法是在另一个切片中列出邻居的deltaYdeltaX索引:

var neighbors = [][]int{
	{-1, 0},
	{1, 0},
	{0, -1},
	{0, 1},
}

然后你可以使用循环遍历neighbors,然后可以在一个地方检查索引:

var result []int
for _, neighbor := range neighbors {
	iy, ix := y+neighbor[0], x+neighbor[1]
	if iy < 0 || iy >= len(matrix) || ix < 0 || ix >= len(matrix[iy]) {
		continue
	}
	result = append(result, matrix[iy][ix])
}

return result

Go Playground上尝试这个。

请注意,这个第二种解决方案也会返回邻居,如果你指定的索引超出了矩阵的范围,但那个元素的邻居仍然在矩阵内部。例如,使用y=-1x=0作为输入,邻居(y+1,x)为0将被返回。

英文:

Both x and y indices of neighbors may be out of range, and not just when being -1, but also when they are >= length of the slice you index with them.

So basically there are 4 neighbors:

(y-1,x), (y+1, x), (y,x-1), (y,x+1)

You have to check all out of bounds cases. Your panic happens on the k := ... line, not inside the for loop. Also returning early in the loop will not handle all elements, and that for is wrong from its roots.

So basically this is how you could do it:

var result []int

if y &gt; 0 {
	result = append(result, matrix[y-1][x])
}
if y &lt; len(matrix)-1 {
	result = append(result, matrix[y+1][x])
}
if x &gt; 0 {
	result = append(result, matrix[y][x-1])
}
if x &lt; len(matrix[y])-1 {
	result = append(result, matrix[y][x+1])
}

return result

This will output (try it on the Go Playground):

[2 2]

Note that if x or y is already invalid, the above code will still panic. If you want to protect against it, you also have to validate x and y, e.g.:

var result []int
if y &lt; 0 || y &gt;= len(matrix) || x &lt; 0 || x &gt;= len(matrix[y]) {
	return result
}

Another approach is to list the deltaY and deltaX indices of neighbors in another slice:

var neighbors = [][]int{
	{-1, 0},
	{1, 0},
	{0, -1},
	{0, 1},
}

And you may use a loop to iterate over neighbors, and then you can check indices in a single place:

var result []int
for _, neighbor := range neighbors {
	iy, ix := y+neighbor[0], x+neighbor[1]
	if iy &lt; 0 || iy &gt;= len(matrix) || ix &lt; 0 || ix &gt;= len(matrix[iy]) {
		continue
	}
	result = append(result, matrix[iy][ix])
}

return result

Try this one on the Go Playground.

Note that this second solution also returns neighbors if you specify indices outside of the matrix if the neighbor of that element falls inside the matrix. E.g. using y=-1, x=0 as the input, the neighbor (y+1,x) being 0 will be returned.

huangapple
  • 本文由 发表于 2022年5月13日 15:29:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/72225886.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定