2014-10-14 1 views
0

하스켈에서 함수를 만들 때 다음을 수행해야합니다.목록에 매핑 할 때 이전 요소를 고려하는 방법은 무엇입니까?

목록의 각 정수에 대해 앞에있는 정수의 수를 확인하십시오. 순간

smallerOnes [1,2,3,5] will have the result [(1,0), (2,1), (3,2), (5,3)] 

나는이 :

smallerOnes :: [Int] -> [(Int,Int)] 
smallerOnes [] = [] 
smallerOnes (x:xs) = 

내가이 문제를 해결하는 방법에 대한 단서를 가지고 있지 않습니다. 재귀는 아마도 여기서 생각하는 방법 일 것이지만, 그 시점에서 나는 그것을 잃어 버릴 것입니다.

답변

3
import Data.List (inits) 
smallerOnes :: [Int] -> [(Int,Int)] 
smallerOnes xs = zipWith (\x ys -> (x, length $ filter (< x) ys)) xs (inits xs) 
+0

윌 네스 (Will Ness)의 첫 번째 대답에서 눈이 멀어서이 답변이 내 모든 문제를 해결한다는 것이 밝혀졌습니다. (전기 커피 업데이트 이후). 모두에게 감사합니다. –

4

여기에서는 기본 케이스로 시작하지 않고 메인 케이스로 시작하는 것이 좋습니다.

이미 절반의 목록을 처리했다고 가정 해 보겠습니다. 이제 우리는 목록의 나머지 부분, 예를 들어 x:xs에 직면 해 있습니다. 우리는 얼마나 많은 정수가 "전에"인지 알고 싶습니다.x보다 작습니다. 그래서 우리는이 요소들을 알아야한다고 말합니다. ys : length [y | y<-ys, y<x]이 답이 될 것입니다. 이것은 또한 일부 내장을 사용하여 코딩 할 수

smallerOnes :: [Int] -> [(Int,Int)] 
smallerOnes [] = [] 
smallerOnes xs = go [] xs 
    where 
     go ys (x:xs) = <result for this x> : <recursive call with updated args> 
     go ys []  = [] 

:

그래서 당신은 각 x의 결과를 생성하여 목록으로 돌아 접두사 ys를 유지하는 내부 기능을 사용해야합니다 고차 함수에서

mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y]) 

mapAccumL is in Data.List과 더 직접적으로 약간의 후 처리 (같은 map snd 또는 무언가) 이상이 필요합니다

scanl :: (a -> b -> a) -> a -> [b] -> [a] 

.

+0

이 대답은 나를 많이 도와줍니다! 내가 아직도 붙어있는 유일한 부분은이 부분이다 : go ys [] = .... –

+0

이렇게 넣으면 : smallerOnes :: [Int] -> [(Int, Int)] smallerOnes [] = [] smallerOnes xs = go [] xs 여기서 은 ys (x : xs) = 길이 [y | y [x, y] [x] go ys [] = [] 많은 오류가 발생합니다 .. –

+0

'[(Int, Int)]'쌍의 목록을 반환해야합니다. 예를 들어 한 쌍을 만듭니다. '(4,5)', 쌍의리스트는'(4,5) : go <...><...>'이됩니다. –

관련 문제