Если вы ищете функциональный пример, вы могли бы, вероятно, сделать (в 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
, хорошо.