Haskell:在数组中最大元素的索引。

huangapple go评论72阅读模式
英文:

Haskell: the index of a maximum element in an Array

问题

Here's the translated code portion:

给定一个`Array`,我需要计算最大元素的索引假设最大元素是唯一的)。

我的当前尝试是

```haskell
maxIndex' :: (Ix i, Ord a) => Array i a -> [i] -> i -> a -> i -> a -> i
maxIndex' arr ids index element maxIndex maxElement
  | length ids == 1 && element > maxElement = index
  | length ids == 1 && element <= maxElement = maxIndex
  | element > maxElement = maxIndex' arr (tail ids) (head ids) (arr ! head ids) index element
  | otherwise = maxIndex' arr (tail ids) (head ids) (arr ! head ids) maxIndex maxElement

maxIndex :: (Ix i, Ord a) => Array i a -> i
maxIndex arr = maxIndex' arr (tail (indices arr)) firstIndex firstMaximum firstIndex firstMaximum
  where
    firstIndex = head (indices arr)
    firstMaximum = arr ! firstIndex

当前的实现是不正确的:

print (maxIndex (array (False,True) [(False,54),(True,104)])) -- 打印 False。
print (maxIndex (array (False,True) [(True,104),(False,54)])) -- 打印 False。

那么,我漏掉了什么?



<details>
<summary>英文:</summary>

Given an `Array`, I need to compute the index of the maximum element (which is assumed to be unique).

My current attempt is:

maxIndex' :: (Ix i, Ord a) => Array i a -> [i] -> i -> a -> i -> a -> i
maxIndex' arr ids index element maxIndex maxElement
| length ids == 1 && element > maxElement = index
| length ids == 1 && element <= maxElement = maxIndex
| element > maxElement = maxIndex' arr (tail ids) (head ids) (arr ! head ids) index element
| otherwise = maxIndex' arr (tail ids) (head ids) (arr ! head ids) maxIndex maxElement

maxIndex :: (Ix i, Ord a) => Array i a -> i
maxIndex arr = maxIndex' arr (tail (indices arr)) firstIndex firstMaximum firstIndex firstMaximum
where
firstIndex = head (indices arr)
firstMaximum = arr ! firstIndex


The current implementation, however, is incorrect:

print (maxIndex (array (False,True) [(False,54),(True,104)])) -- Prints False.
print (maxIndex (array (False,True) [(True,104),(False,54)])) -- Prints False.


So, what am I missing?

</details>


# 答案1
**得分**: 1

你的 `maxIndex` 函数非常复杂,说实话我不明白你在做什么。一般来说,如果你需要大量使用 `head`、`tail` 和显式递归,那么已经出现了问题。最简单的方法是将数组转化为一个成对的链表 `(索引, 元素)`,通过成对元素的第二部分进行比较,然后获取第一个(即 `索引`)。

```haskell
import Data.Array
import Data.Function (on)
import Data.List (maximumBy)

-- 注意 maximumBy 是偏函数
maxIndex = fst . maximumBy (compare `on` snd) . assocs 
--         |     |                              |- (索引, 数组元素) 的列表
--         |     |- 使用自定义比较函数进行最大值查找。在本例中,比较的是元组中的第二个元素
--         |- 获取元组的第一个元素
main = do  
  let arr = array (False,True) [(False,54),(True,104)]
  print $ maxIndex arr 
英文:

Your maxIndex function is very complicated, and honestly I don't understand what you are doing. In general, If you are doing a lot of head, tail and explicit recursion something has gone already wrong. The easiest approach is to transform the array in a linked list of pairs (index, element), compare them by the second element of the pair, and get the first one (the index)

import Data.Array
import Data.Function (on)
import Data.List (maximumBy)

-- Notice maximumBy is partial
maxIndex = fst . maximumBy (compare `on` snd) . assocs 
--         |     |                              |- the list of (index, array_element)
--         |     |- maximum using a custom comparision function. In this case, compare on second element in the tuple
--         |- get the first element of the tuple
main = do  
  let arr = array (False,True) [(False,54),(True,104)]
  print $ maxIndex arr 

答案2

得分: 0

找到符合我的经验水平的代码部分:

maxIndex :: (Ix i, Ord a) => Array i a -> i
maxIndex arr = fst (sortBy (\(_,a) (_,b) -> compare b a) (assocs arr) !! 0)
英文:

Found that meets my experience level:

maxIndex :: (Ix i, Ord a) =&gt; Array i a -&gt; i
maxIndex arr = fst (sortBy (\(_,a) (_,b) -&gt; compare b a) (assocs arr) !! 0)

huangapple
  • 本文由 发表于 2023年5月22日 20:22:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76306159.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定