maxTwo 实现 Haskell

发布于 2025-01-11 14:22:35 字数 647 浏览 0 评论 0原文

给定一个整数列表xs,找到两个最大值并返回 它们成对(最大的在前)。应保留最大的重复项 (包含)在输出中。请勿修改原始列表。

这是我想出的,但它并没有给出正确的答案。这是代码,第二部分是终端运行:

minInt = minBound :: Int

maxTwoHelper1 :: [Int] -> (Int, Int)
maxTwoHelper1 (x : xs) = maxTwoHelper2 minInt minInt xs

maxTwoHelper2 :: Int -> Int -> [Int] -> (Int, Int)
maxTwoHelper2 first second [] = (first, second)
maxTwoHelper2 first second (x : xs)
  | x >= first = maxTwoHelper2 x second xs
  | x >= second = maxTwoHelper2 first x xs
  | otherwise = maxTwoHelper2 first second xs
*Main> maxTwoHelper1 [1,0,-1]
(0,-1)

Given a list of integers xs, find the two largest values and return
them in a pair (largest first). Largest duplicates should be preserved
(included) in the output. Do not modify the original list.

This is what I came up with but it did not quite give the correct answer. Here is the code and the second section is the terminal run:

minInt = minBound :: Int

maxTwoHelper1 :: [Int] -> (Int, Int)
maxTwoHelper1 (x : xs) = maxTwoHelper2 minInt minInt xs

maxTwoHelper2 :: Int -> Int -> [Int] -> (Int, Int)
maxTwoHelper2 first second [] = (first, second)
maxTwoHelper2 first second (x : xs)
  | x >= first = maxTwoHelper2 x second xs
  | x >= second = maxTwoHelper2 first x xs
  | otherwise = maxTwoHelper2 first second xs
*Main> maxTwoHelper1 [1,0,-1]
(0,-1)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

咿呀咿呀哟 2025-01-18 14:22:35

您的 maxTwoHelper1 正在删除 x,它应该考虑所有元素,因此:

maxTwoHelper1 :: [Int] -> (Int, Int)
maxTwoHelper1 xs = maxTwoHelper2 minBound minBound xs

您的 maxTwoHelper2 还包含错误:如果 x > ;=firstx 是最大的,first 第二大,所以:

maxTwoHelper2 :: Int -> Int -> [Int] -> (Int, Int)
maxTwoHelper2 first second [] = (first, second)
maxTwoHelper2 first second (x : xs)
| x >= first = maxTwoHelper2 x first xs --

Your maxTwoHelper1 is dropping the x, it should consider all elements, so:

maxTwoHelper1 :: [Int] -> (Int, Int)
maxTwoHelper1 xs = maxTwoHelper2 minBound minBound xs

Your maxTwoHelper2 also contains an error: in case x >= first, x is the largest, and first the second largest, so:

maxTwoHelper2 :: Int -> Int -> [Int] -> (Int, Int)
maxTwoHelper2 first second [] = (first, second)
maxTwoHelper2 first second (x : xs)
  | x >= first = maxTwoHelper2 x first xs  -- 🖘 first as second largest
  | x >= second = maxTwoHelper2 first x xs
  | otherwise = maxTwoHelper2 first second xs
燃情 2025-01-18 14:22:35

最简单的方法是使用 sortBy

import Data.List (sortBy)
import Data.Function (on)
import Data.Ord (Down (..))

maxTwo :: (Ord a, Bounded a) => [a] -> (a, a)
maxTwo xs = case sortBy (compare `on` Down) xs of
  [] -> (minBound, minBound)
  [biggest] -> (biggest, minBound)
  biggest : second : _ -> (biggest, second)

-- Or, if you don't mind "can't happen" errors:

maxTwo :: (Ord a, Bounded a) => [a] -> (a, a)
maxTwo xs = case sortBy (compare `on` Down) $ minBound : minBound : xs of
  biggest : second : _ -> (biggest, second)
  _ -> error "Impossible!"

这是高效的,因为 sortBy 函数使用增量排序(它恰好是一种惰性自下而上的排序)合并排序,但也有堆排序和快速排序的增量版本可用)。只需要O(n + k * log k)的时间即可获得对n个元素进行排序的结果的前k个元素。 查看这些幻灯片以获取证明。因此,获取任何固定k(在本例中为2)的k最大元素需要O(n)时间。

The easiest way is to use sortBy:

import Data.List (sortBy)
import Data.Function (on)
import Data.Ord (Down (..))

maxTwo :: (Ord a, Bounded a) => [a] -> (a, a)
maxTwo xs = case sortBy (compare `on` Down) xs of
  [] -> (minBound, minBound)
  [biggest] -> (biggest, minBound)
  biggest : second : _ -> (biggest, second)

-- Or, if you don't mind "can't happen" errors:

maxTwo :: (Ord a, Bounded a) => [a] -> (a, a)
maxTwo xs = case sortBy (compare `on` Down) $ minBound : minBound : xs of
  biggest : second : _ -> (biggest, second)
  _ -> error "Impossible!"

This is efficient because the sortBy function uses an incremental sort (it happens to be a lazy bottom-up merge sort, but there are also incremental versions of heapsort and quicksort available). It only takes time O(n + k * log k) to get the first k elements of the result of sorting n elements. See these slides for a proof. So getting the k biggest elements for any fixed k (in this case 2) takes O(n) time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文