你如何检查一个序列是否是 R 中的 'almost increasing sequence'?
How can you check whether a sequence is an 'almost increasing sequence' in R?
一个序列(例如 c(1,2,3,4))几乎是递增的,当我们可以从序列中恰好删除一个元素并得到一个严格递增的序列(即 a0 < a1 < ... < an ).我试图找到一种方法来检查序列是否几乎在增加。如果是,我想 return TRUE;如果不是,我想输出 FALSE。我已经走到这一步了:
solution <- function(sequence) {
sequence1 <- unlist(sequence)
if (length(sequence1) == 1) {
next
}
count <- 0
for (i in (length(sequence1) - 1)) {
if (sequence1[i + 1] > sequence1[i]) {
next
} else if (((sequence1[i + 2] > sequence1[i]) & count == 0) & i !=
length(sequence1)-1) {
sequence1 <- sequence1[- (i + 1)]
count <- count + 1
} else if ((sequence1[i + 1] > sequence1[i - 1]) & count == 0 & i != 1) {
sequence1 <- sequence1[-i]
count <- count + 1
} else {
return(FALSE)
}
}
return(TRUE)
}
我使用 unlist() 是因为 codesignal 出于某种原因不接受您在函数内引用函数参数。这适用于某些序列:solution(c(4,1,5)) correctly returns TRUE。它对其他人不起作用:解决方案 (c(1, 1, 1, 2, 3)) 错误 returns TRUE。 solution(c(2,1,2,1)) 正确地 returns FALSE 而 solution(c(1,2,1,2)) 错误地 returns TRUE。我对正在发生的事情失去了控制。不知道有没有人能发现什么?
澄清:我的代码的基本思想是遍历序列,并为每个元素检查其右邻元素是否为更大的数字。如果不是,那么我们有两个选择:去掉 i 或去掉 i+1,所以我依次检查它们。由于我们只能进行一项更改,因此我添加了条件,即如果计数为 1,则我们跳至完成。另外,如果索引是 1 那么我们不能检查 i-1,如果索引是 length(sequence)-1,那么我们不能检查 i+2,所以我添加了这些条件以确保如果合适,我的代码会跳到另一个选项。
这是一个适合我的解决方案。这个想法是 diff(x)
在 x
中的每个向下步骤都有负元素。例如,如果 x
严格递增,则 min(diff(x))
为正。如果 diff(x)[i] <= 0
恰好有一个索引 i
,我们必须检查删除 x[i]
或删除 x[i+1]
是否会使序列严格递增。以下函数通过了我尝试过的所有测试:
check_almost <- function(x) {
if (length(x) < 2) {
return(TRUE)
}
d <- diff(x)
i <- which(d <= 0)
if (length(i) == 0) {
return(TRUE) # strictly increasing
} else if (length(i) > 1) {
return(FALSE)
}
return(i == 1 || # we can remove x[1]
i == length(d) || # we can remove x[length(x)]
d[i-1]+d[i] > 0 || # we can remove x[i]
d[i] + d[i+1] > 0) # we can remove x[i+1]
}
一个序列(例如 c(1,2,3,4))几乎是递增的,当我们可以从序列中恰好删除一个元素并得到一个严格递增的序列(即 a0 < a1 < ... < an ).我试图找到一种方法来检查序列是否几乎在增加。如果是,我想 return TRUE;如果不是,我想输出 FALSE。我已经走到这一步了:
solution <- function(sequence) {
sequence1 <- unlist(sequence)
if (length(sequence1) == 1) {
next
}
count <- 0
for (i in (length(sequence1) - 1)) {
if (sequence1[i + 1] > sequence1[i]) {
next
} else if (((sequence1[i + 2] > sequence1[i]) & count == 0) & i !=
length(sequence1)-1) {
sequence1 <- sequence1[- (i + 1)]
count <- count + 1
} else if ((sequence1[i + 1] > sequence1[i - 1]) & count == 0 & i != 1) {
sequence1 <- sequence1[-i]
count <- count + 1
} else {
return(FALSE)
}
}
return(TRUE)
}
我使用 unlist() 是因为 codesignal 出于某种原因不接受您在函数内引用函数参数。这适用于某些序列:solution(c(4,1,5)) correctly returns TRUE。它对其他人不起作用:解决方案 (c(1, 1, 1, 2, 3)) 错误 returns TRUE。 solution(c(2,1,2,1)) 正确地 returns FALSE 而 solution(c(1,2,1,2)) 错误地 returns TRUE。我对正在发生的事情失去了控制。不知道有没有人能发现什么?
澄清:我的代码的基本思想是遍历序列,并为每个元素检查其右邻元素是否为更大的数字。如果不是,那么我们有两个选择:去掉 i 或去掉 i+1,所以我依次检查它们。由于我们只能进行一项更改,因此我添加了条件,即如果计数为 1,则我们跳至完成。另外,如果索引是 1 那么我们不能检查 i-1,如果索引是 length(sequence)-1,那么我们不能检查 i+2,所以我添加了这些条件以确保如果合适,我的代码会跳到另一个选项。
这是一个适合我的解决方案。这个想法是 diff(x)
在 x
中的每个向下步骤都有负元素。例如,如果 x
严格递增,则 min(diff(x))
为正。如果 diff(x)[i] <= 0
恰好有一个索引 i
,我们必须检查删除 x[i]
或删除 x[i+1]
是否会使序列严格递增。以下函数通过了我尝试过的所有测试:
check_almost <- function(x) {
if (length(x) < 2) {
return(TRUE)
}
d <- diff(x)
i <- which(d <= 0)
if (length(i) == 0) {
return(TRUE) # strictly increasing
} else if (length(i) > 1) {
return(FALSE)
}
return(i == 1 || # we can remove x[1]
i == length(d) || # we can remove x[length(x)]
d[i-1]+d[i] > 0 || # we can remove x[i]
d[i] + d[i+1] > 0) # we can remove x[i+1]
}