haskell을 배우고 conseq
크기 n의 연속 요소 목록을 반환하는 함수 를 구현하려고합니다 .
conseq :: Int -> [Int] -> [[Int]]
conseq n x
| n == length(x) = [x]
| n > length(x) = [x]
| otherwise = [take n x] ++ (conseq n (drop 1 x))
이것은 올바르게 작동합니다.
> take 5 $ conseq 2 [1..10]
[[1,2],[2,3],[3,4],[4,5],[5,6]]
그러나 [1..]
대신 통과 [1..10]
하면 프로그램이 무한 루프에 빠집니다.
내가 이해했듯이 haskell은 게으른 평가를 가지고 있으므로 여전히 동일한 결과를 얻을 수 있어야합니까? 그렇 length
습니까? 길이가보다 커지면 처음 두 조건이 거짓으로 평가되지 n
않습니까?
내가 무엇을 오해 했습니까?
사용 length
이 좋은 생각이 아닌 주된 이유 중 하나 는 무한 목록에서 평가해야 할 때 무한 루프에 갇히기 때문입니다.
그러나 좋은 소식은 length
. 또한 시간 복잡성을 악화시킬 것입니다. 두 개의 열거 자로 작업 할 수 있습니다. 하나는 다른 하나보다 n-1 자리 앞서 있습니다. 이 열거자가 목록의 끝에 도달하면 첫 번째 열거 자에 여전히 n-1 개의 요소 가 있음을 알고 있으므로 값 생성을 중지 할 수 있습니다.
conseq :: Int -> [a] -> [[a]]
conseq n ys = go (drop (n-1) ys) ys
where go [] _ = []
go (_:as) ba@(~(_:bs)) = take n ba : go as bs
이것은 우리에게 다음을 제공합니다 :
Prelude> conseq 3 [1 ..]
[[1,2,3],[2,3,4],[3,4,5],[4,5,6],[5,6,7],[6,7,8],[7,8,9],[8,9,10],[9,10,11],[10,11,12],[11,12,13],[12,13,14],[13,14,15],[14,15,16],[15,16,17],[16,17,18],[17,18,19],[18,19,20],[19,20,21],[20,21,22],[21,22,23],[22,23,24],[23,24,25],[24,25,26],[25,26,27],…
Prelude> conseq 3 [1 .. 4]
[[1,2,3],[2,3,4]]
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다