Если вы ищете функциональный пример, вы, вероятно, могли бы сделать (в Ruby)
def derivative_signs(list)
(0..list.length-2).map { |i| (list[i+1] - list[i]) <=> 0 }
## <=> is the "rocketship" operator which is basically: be -1 if number is negative
## be 0 if number is zero
## be 1 if number is positive
## Alternatively, one could use x / x.abs, with an exception if x == 0
end
def derivative(list)
(0..list.length-2).map { |i| list[i+1] - list[i] }
end
Исходя из исчисления, минимумы/максимумы - это когда первая производная меняет знак. Таким образом, можно просмотреть derivative_signs(arr)
и найти все изменения знака.
first_derivative_signs = derivative_signs(arr)
# => [1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1]
В качестве альтернативы вы также можете сделать
second_derivative = derivative(derivative_signs(arr))
В списке, который вы предоставили, вы получите:
[0, 0, 0, -2, 0, 2, 0, 0, -2, 0, 0, 2]
Ясно видно, что значения со второй производной -2
являются максимальными, а значения со второй производной 2
— минимальными. Индекс второй производной равен индексу исходного списка + 1. Таким образом, second_derivative[4]
, то есть -2
, соответствует arr[5]
(7), что является максимумом.
Почему мы делаем «нормальную» производную во второй раз вместо производной_знака?
Это связано с тем, что когда значение повторяется дважды подряд, вы получите нежелательное поведение.
Например, рассмотрим
[1, 3, 6, 6, 7, 5, 4, 6, 9, 10, 8, 7, 5, 10]
# first_derivative_signs => [1, 1, 0, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1]
# second_derivative_signs => [0, -1, 1, -1, 0, 1, 0, 0, -1, 0, 0, 1]
# second_derivative => [0, -1, 1, -2, 0, 2, 0, 0, -2, 0, 0, 2]
Обратите внимание, что second_derivative_signs
выдает нам несколько "ложных" минимумов/максимумов, в то время как second_derivative
, когда мы проверяем только -2
и 2
, является хорошим.
person
Justin L.
schedule
06.10.2010