2011-01-19 3 views
11

누적 합계를 반환하는 함수를 작성하십시오. 예 : running [1,2,3,5]는 [1,3,6,11]입니다. 이 함수를 작성하면 list간에 모든 값의 최종 합계를 반환 할 수 있습니다. 어떻게 하나씩 나눌 수 있습니까?하스켈에서 목록 누적 합계 계산

sumlist' xx=aux xx 0 
    where aux [] a=a 
      aux (x:xs) a=aux xs (a+x) 

답변

9

:

sumlist' xx = aux xx 0 
    where aux [] a = [] 
      aux (x:xs) a = (a+x) : aux xs (a+x) 

가이 종류를 표현하는 더 관용적 하스켈이다 그러나 접거나 스캔 한 것.

sumList xs = tail.reverse $ foldl acc [0] xs where 
    acc (y:ys) x = (x+y):y:ys 

또는 pointfree : scanl1는 "표준"솔루션은 분명하지만

25

난 당신이 반환 된 목록에 각 중간 값을 목록에 걸쳐 주어진 기능을 적용하고,보고

scanl1 (+) *your list here* 

scanl1 같은 scanl1과의 조합 (+), 그래서 뭔가를하려는 생각합니다.

등이, 의사 코드에 그것을 밖으로 쓰기

scanl1 (+) [1,2,3] 

것 출력과 같은 목록 :

또는 다른 말로

[1, 1 + 2, 1 + 2 + 3] 
,

[1, 3, 6] 

Learn You A Haskell이 많이있다 스캔들, 폴드 (folds), 그리고 훨씬 더 많은 하스켈 (Haskell)의 좋은 점들에 대한 훌륭한 예제들과 설명들.

희망이 도움이됩니다.

당신은 단순히 각 단계의 결과에 a+x을 앞에 추가하고 기본 케이스로 빈 목록을 사용하여 목록을 생성하여 기능을 조정할 수 있습니다
3

, 당신이 foldl 함께 할 수있는 방법을 볼 여전히 교훈입니다

sumList = tail.reverse.foldl acc [0] where 
    acc (y:ys) x = (x+y):y:ys 

다음은 추한 짐승입니다 힘 접근 :

sumList xs = reverse $ acc $ reverse xs where 
    acc [] = [] 
    acc (x:xs) = (x + sum xs) : acc xs 

을 사용하는 귀여운 (그러나 성능은 좋지 않은) 솔루션이 있습니다.:

sumList xs = tail $ map sum $ inits xs 

다시의 pointfree :

다른 질문에
sumList = tail.map sum.inits 
+0

@ sepp2k : 목록의 오른쪽에서 시작하면 왼쪽에 오는 요소의 합계를 어떻게 구합니까? – Landei

+0

@ Lamdei : 죄송합니다. 나는 옳다고 생각하지 않았습니다. 그러나 게으르지 않은 것은 여전히 ​​foldl (또는 무차별 접근법)을 사용하지 않는 좋은 이유입니다. – sepp2k

+1

왜 '리버스'입니까? 'sumList = (\ snd \'[]). foldl (\\ (a, k) x -> (a + x, k. (a + x :))) (0, id)'는 정방향으로 잘 동작합니다. – ephemient

0

관련 나는이 방법을 발견 :

rsum xs = map (\(a,b)->a+b) (zip (0:(rsum xs)) xs) 

나는 그것도 매우 효율적이라고 생각합니다.