2012-12-12 2 views
3

어떻게 목록의 예에서 가장 자주 값을 얻을 수 있습니다 :하스켈 - 대부분의 자주 값

[1,3,4,5,6,6] -> output 6 
[1,3,1,5] -> output 1 

임 내 자신의 기능에 의해 그것을 얻으려고 노력하지만 난 너희들이 나를 도울 수 달성하지 못할?

내 코드 :

여기
del x [] = [] 
del x (y:ys) = if x /= y 
      then y:del x y 
      else del x ys 



obj x []= [] 
obj x (y:ys) = if x== y then y:obj x y else(obj x ys) 

tam [] = 0 
tam (x:y) = 1+tam y 

fun (n1:[]) (n:[]) [] =n1 
fun (n1:[]) (n:[]) (x:s) =if (tam(obj x (x:s)))>n then fun (x:[]) ((tam(obj x (x:s))):[]) (del x (x:s)) else(fun (n1:[]) (n:[]) (del x (x:s))) 

rep (x:s) = fun (x:[]) ((tam(obj x (x:s))):[]) (del x (x:s)) 
+4

당신이 시도 무엇을 게시하시기 바랍니다. – luqui

+1

태그가 지정된 재귀가 왜 발생합니까? –

+0

재귀와 함께하고 싶습니다 – Urah

답변

3

은 몇 가지 제안

del은 필터를 사용하기보다는 자신의 재귀를 작성 구현 될 수있다. 당신의 정의에 실수가 있었는데 삭제하는 동안 ys이 아니라 y이 아닌 것이 필요했습니다.

del x = filter (/=x) 
obj

상이한 필터 기능 del 유사하다. 마찬가지로 정의에서 ys이 아니라 y이 아닌 obj을 입력해야합니다.

obj x = filter (==x) 

tamlength 기능 당신은 n1n에 대한 목록을 보관할 필요가없는

-- tam = length 

입니다. 알고리즘을 변경하지는 않았지만 코드를 더 읽기 쉽게 만들었습니다.

fun n1 n [] =n1 
fun n1 n [email protected](x:s) | length (obj x xs) > n = fun x (length $ obj x xs) (del x xs) 
        | otherwise    = fun n1 n $ del x xs 

rep [email protected](x:s) = fun x (length $ obj x xs) (del x xs) 

또 다른 방법은 매우 최적의하지만 훨씬 더 읽을 수없는 내가이 코드가 무엇을하고 있는지 간단히 설명하려고합니다

import Data.List 
import Data.Ord 

rep :: Ord a => [a] -> a 
rep = head . head . sortBy (flip $ comparing length) . group . sort 

입니다. 마음에 드는 첫 번째 아이디어는 모든 요소의 빈도를 찾는 것입니다. 따라서 가장 빈번한 요소를 찾아야합니다. 이제 group은 인접한 유사한 요소를 결합하는 함수입니다.

> group [1,2,2,3,3,3,1,2,4] 
[[1],[2,2],[3,3,3],[1],[2],[4]] 

그래서 난 그냥 요소의 가장 많은 하위 목록을 찾는 감소 최대 주파수 요소를 찾기 서로

> sort [1,2,2,3,3,3,1,2,4] 
[1,1,2,2,2,3,3,3,4] 

> group . sort $ [1,2,2,3,3,3,1,2,4] 
[[1,1],[2,2,2],[3,3,3],[4]] 

에 인접 동일한 요소를 가지고 정렬을 사용했다. 주어진 비교 기능에 따라 정렬 할 수있는 함수 sortBy이 있습니다. 따라서 기본적으로 하위 목록의 length을 정렬했습니다 (이 플립은 오름차순보다는 오름차순으로 정렬을 정렬합니다).

> sortBy (flip $ comparing length) . group . sort $ [1,2,2,3,3,3,1,2,4] 
[[2,2,2],[3,3,3],[1,1],[4]] 

지금 당신은 가장 큰 주파수를 가진 요소를 얻을 수 head 두 번 걸릴 수 있습니다.당신은 당신이 달성하고자하는 것을 수행하는 코드에서 몇 가지 아이디어를 얻을하고자하는 경우

+0

최종 작업 코드 스 니펫을 제외한 올바른 대답은 설명 없음. – luqui

+0

@luqui 예를 들어 "좋은 답변입니다. 마지막 스 니펫에 대해 약간의 설명을 추가 할 수 있습니까?" – AndrewC

+0

@luqui 나는 마지막 스 니펫이 충분히 읽기 쉽다고 생각하지만, 내가하고있는 일에 대해 더 많은 정보를 추가 할 것이다. 또한 두 가지 작업 버전이 있습니다 - 첫 번째 코드는 약간 수정 된 코드이고 다른 하나는 더 읽기 쉬운 버전입니다. – Satvik

6

, 여기에 예입니다 Satvik의 마지막 제안에 확장

import Data.List (nub, maximumBy) 
import Data.Function (on) 

mostCommonElem list = fst $ maximumBy (compare `on` snd) elemCounts where 
    elemCounts = nub [(element, count) | element <- list, let count = length (filter (==element) list)] 
+0

죄송 합니다만, 원칙적으로 설명없이 완전한 구현을 하향 표시합니다. 네가 그걸 앞섰다는 것을 안다.하지만 ... – luqui

+7

@luqui 원칙적으로 나는 낮은 인원으로 확실하게 도움을 얻으려는 사용자를 downvoting하기 전에 두 번 생각하고 대신 그들의 대답을 향상시키는 방법에 대해 공손하고 건설적이고 긍정적 인 제안을하기 위해 노력합니다. 당신은 ybz3의 담당자에게 5 % 닦아주었습니다. 나는 당신에게서 900 명의 담당자를 얻는 것과 같았습니다. 그리고 당신은 오래전에 당신의 담당자에 대해 걱정하는 것을 멈추었습니다. 나는 도움이되지 않는 부주의 한 물건을 downvoting하는 주저없이 가지고있다. 그러나 그것은 이것이 무엇인지가 아니다. – AndrewC

+1

@luqui Urah가 자신의 기능을 사용하여이를 구현하고자했습니다. 기존 코드를 사용하여 코드를 작성 했으므로 Urah가 달성하기를 원하는 코드와 거의 일치하지 않습니다. 그것은 단서로 의도되었습니다. - 스스로 구현하기를 원할 때 다른 아이디어를 얻기 위해 다른 사람의 코드를 봅니다. – ljedrz

7

, 당신은 Control.Arrow에서 (&&&) :: (b -> c) -> (b -> c') -> (b -> (c, c')) (참고를 사용할 수 나는 간단하게하기 위해 그 타입 시그니처에서 a = (->)을 대체하여 decorate-sort-undecorate transform을 깨끗하게 수행했다.

mostCommon list = fst . maximumBy (compare `on` snd) $ elemCount 
     where elemCount = map (head &&& length) . group . sort $ list 

head &&& length 함수 [b] -> (b, Int) 입력 갖는다. 목록을 첫 번째 요소의 튜플과 길이로 변환하므로 group . sort과 결합하면 목록에서 각 값의 목록이 발생한 횟수와 함께 표시됩니다.


또한 mostCommon []으로 전화하면 어떤 일이 일어나는지 생각해야합니다. 요소가 전혀 없으므로 분명한 가치가 없다. 그대로, 제안 된 모든 솔루션 (내 포함)은 빈 목록에 실패합니다. 이는 하스켈에게는 좋지 않습니다. 정상적인 일은 Maybe a을 반환하는 것이며, Nothing은 오류 (이 경우 비어있는 목록)를 나타내며 Just a은 "실제"반환 값을 나타냅니다. 예 : 일부 기능 (일부의 입력 값에 대한 정의되는 함수)는 뷰의 부호 안전성 관점에서 끔찍한 같이

mostCommon :: Ord a => [a] -> Maybe a 
mostCommon [] = Nothing 
mostCommon list = Just ... -- your implementation here 

이 훨씬 더 좋은 것이다. 패턴 일치 (NothingJust x에 일치) 및 Data.Maybe (바람직하게는 fromMaybemaybe이 아닌 fromJust)의 기능을 사용하여 Maybe 값을 조작 할 수 있습니다.

+0

나는 완전한 구현 방식에 대한 힌트를보기를 원했을 것이다. 어떻게 작동하는지에 대해 최소한의 설명을 주셔서 감사합니다. 비록 그것이 OP를 위해 아마도 너무 앞서 있다고 생각 하긴하지만. – luqui

+1

@ 루 퀴 (lluqui) 고급이 아닌 문제에 대한보다 진보 된 솔루션을 사람들이보기에 매우 교육적이므로 Control을 만날 때가 많습니다. 실제를위한 Arrow는 일부 기능을 잘 알고 있습니다. 또한 전문가 프로그래머가 문제에 대해 어떻게 생각 하는지를 교육하는 것입니다. 사이트 방문자는 모두 OP가 아닙니다. 스택 오버플로는 영구 참조로 설계되었습니다. 영리한 대답은 직접적인 대답과 함께 중요한 부분을 차지합니다. – AndrewC

0

이미 argmax 기능이 있다고 가정합시다. 자신의 또는 더 나은 작성할 수 있습니다, 당신은 list-extras 패키지를 재사 용할 수 있습니다. 어쨌든 패키지를 살펴보실 것을 강력히 권해드립니다.

그리고, 꽤 쉽게 :

import Data.List.Extras.Argmax (argmax) 

-- >> mostFrequent [3,1,2,3,2,3] 
-- 3 
mostFrequent xs = argmax f xs 
    where f x = length $ filter (==x) xs