2010-11-27 2 views

답변

19

나는 당신이 옳다고 생각합니다. 모든 꼬리가 다르기 때문에 목록의 척추를 공유 할 수 없습니다. 따라서 접두어 목록을 완전히 평가 한 경우 전체 Θ (n) 공간이 필요하며 생성 시간은 Ω (n)입니다.

작성한 함수의 (느슨한 버전)은 Data.Listinits으로 제공됩니다.

그래도 할 수있는 최적화가 있습니다. 이 방정식은 다음을 유지합니다.

map (foldl f z) . inits = scanl f z 

scanl은 선형 시간으로 실행됩니다. 따라서 각 접두사에 대해 왼쪽 접기로하려는 작업을 구사할 수 있다면 접두사 목록 작성의 2 차적 복잡성을 피할 수 있습니다.

+2

+1 scanl에 대한 좋은 아이디어 –

3

표현에 종속적이지 않습니까? 리스트를 연속 된 스토리지와 시작 및 종료 인덱스 (bytestrings과 유사)로 표현하면 스토리지를 공유 할 수 있으며 인덱스 목록을 작성하기 위해 한 번 트래버스해야합니다. 알고리즘은 변하지 않을 것입니다. 이 특정 사용 사례의 경우 snoc 목록 (바이너리 목록이지만 목록의 시작이 아니라 끝에서 중첩 됨)을 사용하면 하위 목록을 공유 할 수 있습니다.

+0

나는 그의 질문이 일반적인 haskell 목록'[]'을 목표로한다는 것이 상대적으로 분명하다고 생각한다. -1 – fuz

+2

이것은 예제의 구문을 보는지 또는 명시된대로 질문하고 있는지에 따라 다릅니다. 허용 된 대답을 감안할 때 바이너리 목록에 대한 제한이 의도되었을 수 있습니다. 그러나 그것은 하스켈의 알고리즘과 같은 단순한 기능적 알고리즘의 속성이 아닙니다.이 특별한 목록 표현입니다. – claus

+0

예, 바이너리 목록의 제한이있었습니다. 나는 그것을 더 분명하게 만들 수 있었다. –

관련 문제