【问题标题】:Index of largest element in an array数组中最大元素的索引
【发布时间】:2013-03-21 15:33:10
【问题描述】:

有谁知道如何从这个函数中获取最大元素的索引:

编程语言是scala

def indexOfLargestElement(arr: Array[Int]): Int = 

例如:

indexOfLargestElement(Array( 1, -6, 4, 5, 2, -1) ) == 3

我不明白-.-

感谢您的帮助!

【问题讨论】:

标签: arrays scala for-loop


【解决方案1】:

以下是单次遍历的方法:

def indexOfLargest(array: Seq[Int]): Int = {
    val result = array.foldLeft(-1,Int.MinValue,0) {
        case ((maxIndex, maxValue, currentIndex), currentValue) =>
            if(currentValue > maxValue) (currentIndex,currentValue,currentIndex+1)
            else (maxIndex,maxValue,currentIndex+1)
        }
    result._1
}

这将使用(已知最大元素的索引;最大元素的值;当前索引)的元组来保存循环中的数据。

【讨论】:

  • 感谢他们对我帮助很大的答案 :) 再问一个问题 .. 可以用 for-loop 做到这一点吗?
【解决方案2】:
// val l = Array(1, -6, 4, 5, 2, -1)
l.indexOf(l.max)

【讨论】:

  • 最多两次遍历。一旦找到元素,第二次遍历就会退出。
【解决方案3】:
scala> :paste
// Entering paste mode (ctrl-D to finish)

@annotation.tailrec final def indexOfLargestElement(a: Array[Int], i: Int = -1, mi: Int = -1, ma: Int = Int.MinValue): Int = {
  val i1 = i + 1
  if (i1 < a.length) {
    val ai1 = a(i1)
    if (ai1 >= ma) indexOfLargestElement(a, i1, i1, ai1)
    else indexOfLargestElement(a, i1, mi, ma)
  } else mi
}

// Exiting paste mode, now interpreting.

indexOfLargestElement: (a: Array[Int], i: Int, mi: Int, ma: Int)Int

scala> indexOfLargestElement(Array(1, -6, 4, 5, 2, -1))
res0: Int = 3

scala> indexOfLargestElement(Array())
res1: Int = -1

scala> indexOfLargestElement(Array(Int.MinValue))
res2: Int = 0

【讨论】:

  • 为什么所有的反对票?这是一个正确的解决方案(而且速度也很快,虽然不是最容易理解的)。
  • 我觉得和@alexwriteshere的一样可以理解,逻辑差不多,只是命令式表达。
【解决方案4】:

我不确定性能如何,因为可能存在昂贵的隐式转换,而且我不知道实际使用了哪种排序算法。

还是这样

scala> val arr = Array( 1, -6, 4, 5, 2, -1)
arr: Array[Int] = Array(1, -6, 4, 5, 2, -1)

scala> arr.zipWithIndex.maxBy(_._1)._2
res1: Int = 3

【讨论】:

  • 这是reduceLeft((x, y) =&gt; if (cmp.gteq(f(x), f(y))) x else y) where implicit cmp: Ordering[B](见TraversableOnce
  • @sourcedelica 您的建议将返回最大元素,而不是索引...还是我遗漏了什么?
【解决方案5】:

我的解决方案很基础,但很容易理解

/** 
 * Returns the max index or -1 if there is no max index
 */
def getMaxIndex(array: Array[Int]): Int = {
  var maxIndex = -1
  var max = Int.MinValue
  for {
    index <- 0 until array.length
    element <- array
  } {
    if (element > max) {
      max = element
      maxIndex = index
    }
  }
  maxIndex
}

和这个差不多

/** 
 * Returns the max index or -1 if there is no max index
 */
def getMaxIndex(array: Seq[Int]): Int = {
    val startIndex = 0
    val result = array.foldLeft(-1, Int.MinValue, startIndex) {
        case ((maxIndex, max, index), element) => {
            if(element > max) (index, element, index+1)
            else (maxIndex, max, index+1)
        }
    }
    result._1
}

【讨论】:

    【解决方案6】:

    与上面的一些解决方案相同,但尾递归更多:

      def getMaxIndex(a: Array[Double]): Int = {
        val l = a.length
    
        def findMax(v: Double, k: Int, i: Int): Int = {
          if (i < l) {
            if (v < a(i)) findMax(a(i), i, i + 1) else findMax(v, k, i + 1)
          } else k
        }
    
        findMax(Double.NegativeInfinity, -1, 0)
      }
    

    真正的尾递归使过程更容易理解。它也更容易调用,只需获取矩阵本身,它不会以任何方式修改矩阵,使其快速。每个元素只访问一次。

    基本上是 Alex Yarmula 和 Andriy Plokhotnyuk 解决方案的更简单版本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-20
      • 1970-01-01
      • 1970-01-01
      • 2018-10-17
      • 2017-04-08
      • 1970-01-01
      • 2022-08-16
      • 2021-11-07
      相关资源
      最近更新 更多