Создание функции findMax (), аналогичной Math.max () [закрыто]

Невозможно использовать обычные методы декомпозиции, потому что они оценивают сезонность, используя, по крайней мере, столько же степеней свободы, сколько и сезонных периодов. Как указывал @useR, вам нужно, по крайней мере, два наблюдения за сезонный период, чтобы иметь возможность отличать сезонность от шума.

Однако, если вы хотите предположить, что сезонность относительно гладкая, вы можете оценить ее с использованием меньших степеней свободы. Например, вы можете аппроксимировать сезонный шаблон с использованием членов Фурье с несколькими параметрами.

df <- ts(c(
2735.869,2857.105,2725.971,2734.809,2761.314,2828.224,2830.284,2758.149,
2774.943,2782.801,2861.970,2878.688,3049.229,3029.340,3099.041,3071.151,
3075.576,3146.372,3005.671,3149.381), start=c(2016,8), frequency=12)

library(forecast)
library(ggplot2)
decompose_df <- tslm(df ~ trend + fourier(df, 2))
trend <- coef(decompose_df)[1] + coef(decompose_df)['trend']*seq_along(df)
components <- cbind(
  data = df,
  trend = trend,  
  season = df - trend - residuals(decompose_df),
  remainder = residuals(decompose_df)
)
autoplot(components, facet=TRUE)

Вы можете отрегулировать порядок членов Фурье как требуется. Я использовал 2 здесь. Для ежемесячных данных максимум, который вы можете использовать, равен 6, но это даст модель с 13 степенями свободы, которая слишком велика, только с 20 наблюдениями. Если вы не знаете о терминах Фурье для сезонности, см. https://otexts.org/fpp2/useful-predictors.html#fourier-series .

Теперь мы можем удалить сезонный компонент, чтобы получить данные с учетом сезонных колебаний.

adjust_df <- df - components[,'season']
autoplot(df, series="Data") + autolayer(adjust_df, series="Seasonally adjusted")

-1
задан Chris Schurmann 19 January 2019 в 02:26
поделиться

5 ответов

Не уверен, что причина использовать 3 if-else if ниже - прямой путь, поскольку цикл for выполняется до длины массива;

function findMax(myArray=[]) {
    aLength = myArray.length;
    if(aLength===0) return;

    var maxNumber = myArray[0];
  for(var i = 0; i < aLength; i++){
    if(myArray[i]>maxNumber) {
      maxNumber=myArray[i];
    }
  } 
  return maxNumber;
}

console.log(findMax([4,2,3,78,0,9]))
0
ответ дан Gowri 19 January 2019 в 02:26
поделиться

Я думаю, что вы задумаетесь над проблемой. Что значит найти максимум массива? Чтобы иметь начальное значение и сравнить его с каждым значением из массива . Если больше , то вы обновите максимальное значение , найденное до сих пор. Если нет, вы ничего не делаете. В конце концов, вы на 100% уверены, что переменная содержит самое большое значение в вашем массиве.

В приведенном ниже коде я инициализировал max до нуля. Если массив пуст, я просто возвращаю max как ноль. Это просто соглашение, которое я сделал, вы можете удалить его, если собираетесь проверять только массивы хотя бы с одним элементом или возвращать что-то еще, если массив пуст.

Далее, если это условие выполнено, это означает, что у меня есть хотя бы один элемент в массиве, поэтому я могу инициализировать max (пока) с первым элементом. Теперь мне нужно только сравнить максимальное значение с другими n - 1 элементами в массиве и обновить максимальное, если это необходимо.

Иногда другие реализации инициализируют максимальное значение с помощью Number.MIN_VALUE. Почему мин? Так что каждое значение в вашем массиве больше этого значения, и вы можете начать итерацию с i = 0; однако, это не работает, если ваш массив имеет Number.MIN_VALUE как элемент.

function findMax(myArray) {
  let len = myArray.length;
  let max = null;
  
  if (len === 0)
    return max;
    
  max = myArray[0];
  
  for (var i = 1; i < len; i++) {
    if (myArray[i] > max)
      max = myArray[i];
  }
  
  return max;
}

let arr = [1, 3, 4, -2, -4, 8, 16, 0, -18, 6];
let empty = [];

console.log(findMax(arr));
console.log(findMax(empty));

Бонус : В javascript также есть несколько интересных вещей, называемых лямбда-функциями. Одним из них является редуктор . Метод redu () выполняет функцию редуктора (которую вы предоставляете) для каждого члена массива, в результате чего получается одно выходное значение. Он работает примерно так же, но он более элегантный и компактный. a является аккумулятором, а e является текущим элементом. Мы просто сравниваем a с e и сохраняем наибольшее значение. Второй параметр (null является начальным значением, как я объяснил ранее). Реализация Math.max с помощью Reduce очень проста:

function findMax(array) {
  return array.reduce((a, e) => a > e ? a : e, null);
}

let arr = [1, 3, 4, -2, -4, 8, 16, 0, -18, 6];
let empty = [];

console.log(findMax(arr));
console.log(findMax(empty));

0
ответ дан Adrian Pop 19 January 2019 в 02:26
поделиться

Вы также можете использовать уменьшение.

Вот пример

const findMax = array => array.reduce((prev, actual) => {
 return actual > prev ? actual : prev;
})

findMax([1,3,4]) // 4

const findMax = array => array.reduce((prev, actual) => {
  return actual > prev ? actual : prev;
})

console.log(findMax([1,19,20]))

0
ответ дан Fernando Colom 19 January 2019 в 02:26
поделиться

это может помочь:

function findMax(arr) {
  let max = arr[0] || -Infinity;
  for (let i of arr)
    max = max > i ? max : i;
  return max;
}

, если вы не можете использовать Math.max () только потому, что у вас есть массив, тогда вы можете попробовать:

Math.max.apply(null, array);

или

[ 112]
0
ответ дан PranshuKhandal 19 January 2019 в 02:26
поделиться

Ваша функция в настоящее время не работает. Например, если вы введете [1, 200, 3, 400], это приведет к 200, а не 400.

Цель этой задачи, кажется, состоит в том, чтобы заставить вас задуматься о том, как реализовать алгоритм для поиска максимального значения в массиве, отсюда и запрет на Math функции.

1127] Когда к такой задаче обращаются, важно думать об этом логически и последовательно. Иногда может быть полезно подумать о том, как вы, человек , решили бы такую ​​проблему. Может быть проще написать свой алгоритм / функцию, когда вы сделали это и разбили логику на шаги. При просмотре массива необходимо выполнить следующие действия (шаги):

  1. Проверить, больше ли текущее число, чем текущее максимальное число.
  2. Если это так, установите максимальное число, равное текущему номеру.
  3. Если это не так, вам не нужно ничего делать. Вместо этого позвольте вашему циклу перейти к следующему числу в вашем массиве
  4. Повторяйте этот цикл, пока вы не посмотрите на все числа в вашем массиве.

Это основная схема работы вашего алгоритма. Тем не менее, вы можете столкнуться с несколькими проблемами с этим. Например, при взгляде на первое число в вашем массиве, что следует считать текущим максимальным числом (поскольку вы еще не видели никаких предыдущих значений)? Эту проблему можно решить, установив текущее максимальное число на первый элемент в вашем массиве в начале, а затем запустив алгоритм, чтобы найти любое число, превышающее максимальное число (первое число) и соответственно обновляет его значение (когда найдено большее число).

Принимая все это во внимание, ваша findMax() функция может быть переписана следующим образом (подробности см. В комментариях к коду):

function findMax(myArray) {
  var maxNumber = myArray[0]; // when we first start, we can set the first element in our array to be the max number - it might not be the max number in the end, but it is a number we can compare the rest of the numbers in our array off of.
  
  for (var i = 1; i < myArray.length; i++) { // loop through our array. (we can start i at 1, because we don't need to check the first element as we have set it to the maxNumber above)
    var currentNumber = myArray[i]; // get the current number from the array.
    if(currentNumber > maxNumber) { // if the current number is greater than our maximum number (which we initially set to the first number in our array) we can change our maxNumber to be the currentNumber:
      maxNumber = currentNumber
    }
  }
  // When we run this code our loop would've finished, meaning we have gone through our entire array and found the maxNumber
  return maxNumber;
}

console.log(findMax([1, 200, , 3, 400])); // Output: 400
[1130 ]

Теперь, если вы действительно педантичны в том, чтобы заставить вашу функцию работать точно так же, как Math.max(), вы можете увидеть этот ответ , который показывает реализацию этого метода в Chrome V8.

Здесь приведена лишь одна реализация того, как можно реализовать алгоритм для поиска наибольшего значения в массиве.

Если вы беспокоитесь о производительности, также важно понимать, что сжатый код не обязательно равен лучшей производительности.

Решение, которое я здесь предоставил, имеет временную сложность из O (N) , где N - количество элементов в вашем массиве. Это означает, что для того, чтобы найти самый высокий элемент в вашем массиве, он должен проверить каждый элемент в вашем массиве. Это может показаться не слишком плохим, но если размер вашего массива увеличивается (скажем, он имеет 1 000 000 номеров), это может занять некоторое время для расчета. Однако, правда в том, что для того, чтобы найти наибольшее число в массиве , вам действительно нужно проверить каждый элемент.

Однако, с учетом вышесказанного, есть другие структуры данных (такие как max-heap ), которые вы можете реализовать, которые могут предоставить вам лучшую временную сложность и производительность. Если вы, например, использовали 'max-heap', и все, что вы хотели сделать, это найти максимальное число, вы можете использовать его таким образом, который позволит вам найти максимальное число (то есть получить корневой узел) в [ 1119] O (1) временная сложность. Это означает, что вы можете мгновенно получить максимальное число из вашей структуры данных. Это не то, что вам нужно реализовать само по себе, скорее это просто то, что нужно знать и иметь в виду.

0
ответ дан Nick Parsons 19 January 2019 в 02:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: