英文:
Almost increasing sequence in Go: how to loop avoiding index out of bound?
问题
所以我正在尝试通过做一些算法挑战来学习Go语言,我目前正在做的一个挑战叫做"almost increasing sequence"。
指令如下:
给定一个整数序列作为数组,确定是否可以通过从数组中移除不超过一个元素来获得严格递增的序列。
-
对于
sequence = [1, 3, 2, 1]
,输出应为almostIncreasingSequence(sequence) = false
; -
这个数组中没有一个元素可以被移除以获得严格递增的序列。
-
对于
sequence = [1, 3, 2]
,输出应为almostIncreasingSequence(sequence) = true
; -
我们可以从数组中移除3,得到严格递增的序列[1, 2]。或者我们可以移除2,得到严格递增的序列[1, 3]。
如果可以移除一个元素以获得严格递增的序列,则函数必须返回true,否则返回false。
我已经用TypeScript完成了这个挑战,不难。但是我想用Go重新编写它,但是我发现在Go中避免"index out of range"错误有点棘手。以下是我目前的代码:
func almostIncreasingSequence(a []int) bool {
var count int = 0
for i := 0; i < len(a); i++ {
if a[i] <= a[i-1] {
count++
if (a[i] <= a[i-2]) && (a[i+1] <= a[i-1]) {
return false
}
}
}
return count <= 1
}
这是我从TypeScript直接转换过来的代码,在TypeScript中它可以正常工作,但是你可以很容易地从我的Go代码中注意到"index out of range"错误发生在迭代时的if a[i] <= a[i-1]
。
在编写Go代码时,有没有什么技巧可以避免比较索引i
和i - 1
或i + 1
时出现"index out of range"错误?
提前感谢!
英文:
So I am trying to learn Go by doing some algorithm challenges, and the one I am currently on is called almost increasing sequence.
The instruction looks like:
>Given a sequence of integers as an array, determine whether it is possible to obtain a strictly increasing sequence by removing no more than one element from the array.
>- For sequence = [1, 3, 2, 1]
, the output should be
almostIncreasingSequence(sequence) = false
;
>There is no one element in this array that can be removed in order to get a strictly increasing sequence.
>- For sequence = [1, 3, 2]
, the output should be
almostIncreasingSequence(sequence) = true
.
>We can remove 3 from the array to get the strictly increasing sequence [1, 2]. Alternately, we can remove 2 to get the strictly increasing sequence [1, 3].
>The function must return true if it is possible to remove one element from the array in order to get a strictly increasing sequence, otherwise return false.
I have finished this in Typescript already, it was not hard. But I am trying to write it again in Go, but I found it is kinda tricky to avoid index out of range
error in Go. Here is my code so far:
func almostIncreasingSequence(a []int) bool {
var count int = 0
for i := 0; i < len(a); i++ {
if a[i] <= a[i-1] {
count++
if (a[i] <= a[i-2]) && (a[i+1] <= a[i-1]) {
return false
}
}
}
return count <= 1
}
This is what I literally converted what I wrote in Typescript and it works fine with Typescript, but as you can easily notice from my Go code index out of range
error occurs when as it iterates, if a[i] <= a[i-1]
.
Are there any tricks to compare an element at index i
and i - 1
or i + 1
avoiding index out of range
error when write code in Go?
Thanks in advance!
答案1
得分: 1
这不是一个技巧。你正在从0
(第一个元素)循环到数组的长度减一,或者上限。当i == len(a) - 1
时,a[i+1]
将超过数组的长度。如果数组中只有3个项,它们的索引将是0
,1
,2
。len(a)
给出的是3
。i < len(a)
的结果是0
到2
。
你还在第一次迭代中从i
中减去了一个值,这基本上是在询问编译器if a[0] <= a[-1]
,这导致a[-1]
超出了数组的边界。你在a[i] <= a[i-2]
中再次这样做。
我相当确定你只需要这样的代码:
func almostIncreasingSequence(a []int) bool {
count := 0 // :=是简写形式。只要它在函数内部,它基本上等同于var。它还推断出类型。
l := len(a) - 1
for i := 0; i < l; i++ {
if a[i] > a[i+1] {
count++
}
}
r := count <= 1
fmt.Println(a, r)
return r
}
结果为:
[1 3 2 1] false
[1 3 2] true
https://play.golang.org/p/8d_3a_PMM2C
如果性能很重要且数组可能很大,请添加对count的检查:
if a[i] > a[i+1] {
count = count + 1
if(count > 1) {
return false;
}
}
它在JavaScript中工作的原因是由于Undefined
的处理方式。
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
console.log(1 < undefined)
console.log(0 < undefined)
const array = []
console.log(array[0] < 0)
console.log(array[-1] < 0)
console.log(array[9999] < 0)
<!-- end snippet -->
由于它设计的目标,JavaScript是一种非常宽容的语言。
英文:
It isn't a trick. You are looping from 0
(first element) through the length of the array minus one, or upper bounds. When i == len(a) - 1
then a[i+1]
is going to exceed the length of the array. If there are only 3 items in it, their indexes will be 0
, 1
, 2
. len(a)
gives you 3
. i < len(a)
results in 0
through 2
.
You are also subtracting from i
on the first iteration which is basically asking the compiler if a[0] <= a[-1]
which results in a[-1]
being outside of the boundaries of the array. You do so again with a[i] <= a[i-2]
.
I'm fairly certain you just need something like:
func almostIncreasingSequence(a []int) bool {
count := 0 // := is shorthand. So long as it is within a func it is basically equiv of var. It also infers the type.
l := len(a) - 1
for i := 0; i < l; i++ {
if a[i] > a[i+1] {
count++
}
}
r := count <= 1
fmt.Println(a, r)
return r
}
Results in:
[1 3 2 1] false
[1 3 2] true
https://play.golang.org/p/8d_3a_PMM2C
If performance is important and the array could be large, add a check for count:
if a[i] > a[i+1] {
count = count + 1
if(count > 1) {
return false;
}
}
The reason it worked in JavaScript is due to how Undefined
is treated.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
console.log(1 < undefined)
console.log(0 < undefined)
const array = []
console.log(array[0] < 0)
console.log(array[-1] < 0)
console.log(array[9999] < 0)
<!-- end snippet -->
It is an incredibly forgiving language due to the terrain it was devised for.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论