在列表中找到最大值并在列表中查找对

时间:2014-04-09 11:52:40

标签: list prolog

我是Haskell的新手,但我在Prolog中写了这个解决方案。

第一个:我必须创建函数或一些将在列表中找到最大值的函数。我想为该解决方案重写我的Prolog功能,或者如果您知道更轻松的解决方案,请在下面写下。

输入:someFunc [1,2,3,3,3,4,4,4,5,5]输出:[3,4]

输入:someFunc [1,2,2,3,4,5]输出:[2]

Prolog代码:

listMax(L, M) :- listMax(L, [], [], M).

listMax([], Seen, MMax, Max) :- 
  (MMax == [] -> 
    Max = Seen
  ; listMax(MMax, [], [], Max)).

listMax([H|T], Seen, MMax, Max) :-
  (member(H, Seen) -> 
    listMax(T, Seen, [H|MMax], Max)
  ; listMax(T, [H|Seen], MMax, Max)).

第二个:我必须创建函数或一些函数,这些函数将找到作为列表中的对重复多次的元素。

输入:someFunc [2,2,2,2,3,3,3,4,4,5]输出:[2,4]

输入:someFunc [1,1,2,2,2,3,3]输出:[1,3]

Prolog代码:

count([], _, 0).
count([H|T], H, R) :- count(T, H, RT), R is RT + 1.
count([H|T], X, R) :- H \= X, count(T, X, R).

add_if_count_is_one(H, T, H)  :- count(T, H, C), 0 is (C+1) mod 2.
add_if_count_is_one(H, T, []) :- count(T, H, C), 0 is C mod 2.
add_if_count_is_one(H, T, []) :- count(T, H, 0).

num_pairs([], []).
num_pairs([H|T], [H1|T1]) :- 
  delete(T, H, TT), 
  num_pairs(TT, T1), 
  add_if_count_is_one(H, T, H1).

listPair(M, RR):- 
  num_pairs(M, R), 
  delete(R,[],RR).

2 个答案:

答案 0 :(得分:0)

您的第二个问题可以通过在Data.List中使用一些更高阶函数来解决:

import Data.List

numPair :: [Integer] -> [Integer]
numPair xs = map head (filter ( even . length) (groupBy (==) xs))

ghci中的演示:

ghci > numPair [2,2,2,2,3,3,3,4,4,5]
[2,4]
ghci > numPair [1,1,2,2,2,3,3] 
[1,3]

您可以使用类似的技巧来解决您的其他问题。浏览Data.List中的功能以熟悉它。

答案 1 :(得分:0)

此代码实现了这两个功能:

import Data.List

-- Case 1
maxOccurrence :: (Ord a) => [a] -> [a]
maxOccurrence = (map head) .  last . occurenceGroup

-- Case 2
maxOccurrenceNumber :: (Ord a) => [a] -> [(a, Int)]
maxOccurrenceNumber =
    (map (\l -> (head l, length l))) .
    last . occurenceGroup

-- Common function
occurenceGroup :: (Ord a) => [a] -> [[[a]]]
occurenceGroup =
        (groupBy (cmp (==))) . (sortBy (cmp compare)) .
        group . sort
    where
        cmp op = \a b -> op (length a) (length b)

occurenceGroup

  1. 在具有相同值的元素将在同一组中之后,按其元素的值对参数列表进行排序和分组
  2. 对第一步的结果进行排序并按其元素的长度分组,此相同长度的元素将在同一组中
  3. occurenceGroup重新排列其参数列表的元素之后,两个函数的实现都是微不足道的,它们只取结果occurenceGroup的最后一个元素,并提取或计算它们所需的信息。


    这是完整的测试程序:

    import Data.List
    
    maxOccurrence :: (Ord a) => [a] -> [a]
    maxOccurrence = (map head) .  last . occurenceGroup
    
    maxOccurrenceNumber :: (Ord a) => [a] -> [(a, Int)]
    maxOccurrenceNumber =
        (map (\l -> (head l, length l))) .
        last . occurenceGroup
    
    occurenceGroup :: (Ord a) => [a] -> [[[a]]]
    occurenceGroup =
            (groupBy (cmp (==))) . (sortBy (cmp compare)) .
            group . sort
        where
            cmp op = \a b -> op (length a) (length b)
    
    ----
    
    lst11, lst12, lst21, lst22 :: [Int]
    lst11 = [1,2,3,3,3,4,4,4,5,5]
    lst12 = [1,2,2,3,4,5]
    lst21 = [2,2,2,2,3,3,3,4,4,5]
    lst22 = [1,1,2,2,2,3,3]
    
    main = do
            putStrLn "Case 1:"
            output lst11
            output $ maxOccurrence lst11
            output lst12
            output $ maxOccurrence lst12
            putStrLn "Case 2:"
            output lst21
            output $ maxOccurrenceNumber lst21
            output lst22
            output $ maxOccurrenceNumber lst22
        where output lst = putStrLn $ show lst