Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 高效查找列表最大值的索引_List_Haskell_Functional Programming - Fatal编程技术网

List 高效查找列表最大值的索引

List 高效查找列表最大值的索引,list,haskell,functional-programming,List,Haskell,Functional Programming,编辑:我一定没有把它写得足够清楚,但我正在寻找一个像下面这样的函数,但不完全是它 给定一个列表,我希望能够找到列表中最大元素的索引 所以,名单!!indexOfMaximum列表==最大列表 我写了一些似乎相当有效的代码,尽管我觉得我正在某处重新发明轮子 indexOfMaximum :: (Ord n, Num n) => [n] -> Int indexOfMaximum list = let indexOfMaximum' :: (Ord n, Num n) =>

编辑:我一定没有把它写得足够清楚,但我正在寻找一个像下面这样的函数,但不完全是它

给定一个列表,我希望能够找到列表中最大元素的索引 所以,名单!!indexOfMaximum列表==最大列表 我写了一些似乎相当有效的代码,尽管我觉得我正在某处重新发明轮子

indexOfMaximum :: (Ord n, Num n) => [n] -> Int
indexOfMaximum list =
   let indexOfMaximum' :: (Ord n, Num n) => [n] -> Int -> n -> Int -> Int
       indexOfMaximum' list' currIndex highestVal highestIndex
          | null list'                = highestIndex
          | (head list') > highestVal = 
               indexOfMaximum' (tail list') (1 + currIndex) (head list') currIndex
          | otherwise                 = 
               indexOfMaximum' (tail list') (1 + currIndex) highestVal highestIndex
   in indexOfMaximum' list 0 0 0
现在我想返回列表中最大n个数字的索引列表

我唯一的解决方案是将前n个元素存储在一个列表中,并用n个迄今为止最大的列表中的比较替换head list'>highestVal


感觉必须有一种比这更有效的方法,我也觉得我没有充分利用Prelude和Data.List。有什么建议吗

一个简单的方法是使用maximum来查找最大的元素,然后使用findindice来查找它的每一次出现。比如:

largestIndices :: Ord a => [a] -> [Int]
largestIndices ls = findIndices (== maximum ls) ls
然而,这并不是完美的,因为maximum是一个部分函数,如果给定一个空列表,它会令人恶心。您可以通过添加[]案例轻松避免这种情况:

这个答案的真正诀窍在于我是如何找到答案的。我以前甚至都不知道findIndices!然而,GHCi有一个整洁的命令:browse

这将列出Data.List导出的每个函数。使用这个,我只是先搜索最大值,然后搜索索引,看看选项是什么。就在findIndex旁边,有findIndecies,非常完美

最后,我不会担心效率,除非您确实看到代码运行缓慢。GHC可以而且确实执行了一些非常积极的优化,因为它的语言是纯的,而且可以不受影响。因此,您唯一需要担心性能的时候是在使用-O2编译之后,您会发现这是一个问题

编辑:如果你想找到前n个元素的索引,这里有一个简单的想法:按降序排列列表,获取前n个唯一元素,用elemindice获取它们的索引,并从中获取前n个索引。我希望这是比较清楚的

下面是我想法的一个快速版本:

nLargestInices n ls = take n $ concatMap (`elemIndices` ls) nums
  where nums = take n . reverse . nub $ sort ls

一个简单的方法是使用maximum来查找最大的元素,然后使用findindies来查找它的每一次出现。比如:

largestIndices :: Ord a => [a] -> [Int]
largestIndices ls = findIndices (== maximum ls) ls
然而,这并不是完美的,因为maximum是一个部分函数,如果给定一个空列表,它会令人恶心。您可以通过添加[]案例轻松避免这种情况:

这个答案的真正诀窍在于我是如何找到答案的。我以前甚至都不知道findIndices!然而,GHCi有一个整洁的命令:browse

这将列出Data.List导出的每个函数。使用这个,我只是先搜索最大值,然后搜索索引,看看选项是什么。就在findIndex旁边,有findIndecies,非常完美

最后,我不会担心效率,除非您确实看到代码运行缓慢。GHC可以而且确实执行了一些非常积极的优化,因为它的语言是纯的,而且可以不受影响。因此,您唯一需要担心性能的时候是在使用-O2编译之后,您会发现这是一个问题

编辑:如果你想找到前n个元素的索引,这里有一个简单的想法:按降序排列列表,获取前n个唯一元素,用elemindice获取它们的索引,并从中获取前n个索引。我希望这是比较清楚的

下面是我想法的一个快速版本:

nLargestInices n ls = take n $ concatMap (`elemIndices` ls) nums
  where nums = take n . reverse . nub $ sort ls

最短路径查找最大元素的最后一个索引

maxIndex list = snd . maximum $ zip list [0 .. ]
如果你想要第一个索引

maxIndex list = snd . maximumBy cmp $ zip list [0 .. ]
  where
    cmp (v,i) (w,j) = case compare v w of
                        EQ -> compare j i
                        ne -> ne

缺点是maximumBy和maximumBy太懒了,所以它们可能会生成较大的thunk。为了避免这种情况,可以像以前一样使用手动递归,但可能需要一些严格的注释,或者使用严格的左折叠和严格的累加器类型,元组不适合这样做,因为foldl'只计算弱头范式,也就是这里最外层的构造函数,因此,您可以在元组组件中构建thunk。

最短路径可以找到最大元素的最后一个索引

maxIndex list = snd . maximum $ zip list [0 .. ]
如果你想要第一个索引

maxIndex list = snd . maximumBy cmp $ zip list [0 .. ]
  where
    cmp (v,i) (w,j) = case compare v w of
                        EQ -> compare j i
                        ne -> ne

缺点是maximumBy和maximumBy太懒了,所以它们可能会生成较大的thunk。为了避免这种情况,可以像以前一样使用手动递归,但可能需要一些严格的注释,或者使用严格的左折叠和严格的累加器类型,元组不适合这样做,因为foldl'只计算弱头范式,也就是这里最外层的构造函数,因此,您可以在元组组件中构建thunk。

此解决方案将每个元素与其索引关联,对列表进行排序,使最小的元素排在第一位,将其反转,使最大的元素排在第一位,获取前n个元素,然后提取索引

maxn n xs = map snd . take n . reverse . sort $ zip xs [0..]

此解决方案将每个元素与其索引关联,对列表进行排序,使最小的元素排在第一位,将其反转,使最大的元素排在第一位,取前n个元素,然后 跟踪索引

maxn n xs = map snd . take n . reverse . sort $ zip xs [0..]

哦,很好的发现:浏览和查找骰子!不过,我想你们误解了一点:我想找出n个最大元素的指数,它们可能不相等。既然你已经指出了findIndices,我正试着用elemIndices烤些东西,但我还是有麻烦。哦。我以为你想找到最大元素的所有索引。我的错。仍然+1的有用性,肯定。哦,很好的发现:浏览和findIndices!不过,我想你们误解了一点:我想找出n个最大元素的指数,它们可能不相等。既然你已经指出了findIndices,我正试着用elemIndices烤些东西,但我还是有麻烦。哦。我以为你想找到最大元素的所有索引。我的不好。当然,还是+1有用。我曾经想过这样的事情,但该死的,现在你这么说听起来效率更高了。谢谢。但是,这至少需要logn,其中N是列表的长度。我认为如果我们使用sortBy flip compare,如果只需要O1个最上面的元素,排序函数的惰性将使这个解决方案基本启动。Doh!我想知道如何最好地反转比较。当翻转参数起作用时,我被反转结果挂断了。谢谢,我曾经想到过这样的事情,但是该死的,现在你这么说听起来效率更高了。谢谢。但是,这至少需要logn,其中N是列表的长度。我认为如果我们使用sortBy flip compare,如果只需要O1个最上面的元素,排序函数的惰性将使这个解决方案基本启动。Doh!我想知道如何最好地反转比较。当翻转参数起作用时,我被反转结果挂断了。谢谢