英文:
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) => Array i a -> i
maxIndex arr = fst (sortBy (\(_,a) (_,b) -> compare b a) (assocs arr) !! 0)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论