制作findMax()函数,类似于Math.max()

时间:2019-01-19 02:26:36

标签: javascript arrays max

所以我的任务是制作一个函数,该函数循环遍历任何给定长度的数组,并返回其中的最大值。

容易吗?不是,当您只能用于循环且没有Math函数时。我了解Math.max(),但我无法在此处实现它,这使我不得不仔细考虑。

我花了大约两个小时的时间,大约花了30分钟进行了非常缓慢的调试,但我想我终于找到了解决方法。这是我想出的:

function findMax(myArray) {
    aLength = myArray.length;
for(var i = 0; i < aLength - 1; i++){

    var maxNumber;
    var currentNumber = myArray[i];
    var nextNumber = myArray[i + 1];
    if(maxNumber > currentNumber){
         maxNumber = maxNumber}

    else if(currentNumber > nextNumber){
         maxNumber = currentNumber;

    } else if (nextNumber > currentNumber){
         maxNumber = nextNumber;
    }

} return maxNumber;

这就像一种魅力,我只是觉得它有点大,也许可以压缩性能?

我知道有些人会说:“为什么要声明一个设置为数组长度的变量,而不是仅仅使用myArray.length在哪里aLength

好吧,我不知道你们是谁,但是Google Chrome的Web开发工具整天都向我抛出了误报,而且它不是在for循环条件语句中读取length属性。

你们如何编写这段代码?

5 个答案:

答案 0 :(得分:3)

这可能会帮助:

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);

Math.max(...array);  // using spread operator in ECMA-script

答案 1 :(得分:3)

目前,您的功能无法正常运行。例如,如果您输入[1, 200, 3, 400],将导致200而不是400

此任务的目的似乎是让您思考如何实现一种算法以在数组中找到最大值,从而禁止使用Math函数。

在执行此类任务时,重要的是要逻辑上和顺序地进行思考。有时,考虑作为人类的人如何解决此类问题可能会很有用。完成此操作并将逻辑分解为步骤后,编写算法/函数可能会更容易。通过数组时,您需要执行以下操作(步骤):

  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

现在,如果您真的想让功能完全像Math.max()一样运行,您会看到this answer,其中显示了Chrome V8对该方法的实现。

这只是关于如何实现算法以在数组中找到最大值的一种实现。

如果您担心性能,那么了解压缩代码不一定等于更好的性能也很重要。

我在此处提供的解决方案的time complexity O(N),其中 N 是数组中元素的数量。这意味着为了找到数组中的最高元素,需要检查数组中的每个元素。这听起来可能还不错,但是如果数组的大小增加(例如,数组有1,000,000个数字),则可能需要一些时间来计算。但是,事实是,要在数组中找到最高编号 ,实际上您需要检查每个元素。

但是,可以这么说,您可以实现其他数据结构(例如max-heap),从而为您提供更好的时间复杂度和性能。例如,如果您要使用“ max-heap”,而您要做的就是找到最大数量,则可以通过以下方式使用它:允许您在<中找到最大数量(即获取根节点) em> O(1)时间复杂度。这意味着您可以立即从数据结构中获取最大数量。本质上,这不是您需要实现的任何东西,而只是您要知道并拥有的东西。

答案 2 :(得分:2)

您也可以使用reduce。

这是一个例子

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]))

答案 3 :(得分:1)

不确定使用以下3个if-else ifs的原因是直接的方法,因为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]))

答案 4 :(得分:0)

我认为您想得太多了。找到一个数组的最大值是什么意思?要具有初始值,然后将其与数组中的每个值进行比较。如果更大,则您更新到目前为止找到的最大值。如果没有,您什么也不做。最后,您可以100%确保该变量包含数组中的最大值。

在下面的代码中,我将max初始化为null。如果数组为空,我只将max作为null返回。这只是我的约定,如果只测试至少包含一个元素的数组,或者如果该数组为空,则返回其他内容,则可以删除它。

接下来,如果通过了此条件,则意味着我在数组中至少有一个元素,因此我可以使用第一个元素初始化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中还有一些很酷的东西,称为lambda函数。其中之一是reduce。 reduce()方法在数组的每个成员上执行reducer函数(由您提供),从而产生单个输出值。它的工作原理相同,但更优雅,更紧凑。 a是累加器,e是当前元素。我们只是将ae进行比较,并保持最大值。第二个参数(null是初始值,正如我之前解释的那样)。用reduce实现Math.max非常简单:

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));