Рассмотрим следующие две функции кумулятивной суммы (cumsum):
cumsum :: Num a => [a] -> [a]
cumsum [] = []
cumsum [x] = [x]
cumsum (x:y:ys) = x : (cumsum $ (x+y) : ys)
и
cumsum' :: Num a => [a] -> [a]
cumsum' x = [sum $ take k x | k <- [1..length x]]
Конечно, я предпочитаю определение cumsum
определению cumsum'
и понимаю, что первое имеет линейную сложность.
Но почему cumsum'
также имеет линейную сложность? Сам take
имеет линейную сложность по длине аргумента, а k
изменяется от 1
до length x
. Поэтому я ожидал квадратичной сложности cumsum'
.
Более того, константа cumsum'
ниже, чем у cumsum
. Это связано с добавлением последнего в рекурсивный список?
ПРИМЕЧАНИЕ: приветствуем любое умное определение совокупной суммы.
РЕДАКТИРОВАТЬ: я измеряю время выполнения, используя (после включения :set +s
в GHCi):
last $ cumsum [1..n]
cumsum'
могла иметь линейную сложность. - person GS - Apologise to Monica   schedule 03.07.2014scanl (+) 0
- person luqui   schedule 03.07.2014last $ cumsum' [1..n]
- person VH-NZZ   schedule 03.07.2014max
, а неlast
. - person GS - Apologise to Monica   schedule 03.07.2014\x -> [take k x | k <- [1..length x]]
равноtail . inits
, за исключением того, что последний не вычисляет длину и не начинает заново для создания каждого подсписка. Ваша функцияmap sum . tail . inits
- person user2407038   schedule 03.07.2014maximum
и, действительно, теперь наблюдаю квадратичную сложность. В некотором смысле я рад, потому что это заставило меня опасаться измерения, ура! Тогда возникает следующий вопрос: как вlast
реализована лень? - person VH-NZZ   schedule 03.07.2014last
, а с Хаскеллом вообще лень.last
проверяет только структуру списка, поскольку это все, что ему нужно сделать, поэтому отдельные элементы не будут принудительно выполнены, и все, кроме последнего элемента, будут просто выброшены. Затем возвращаемое значение (т.е. последний элемент) принудительно распечатывается. - person GS - Apologise to Monica   schedule 03.07.2014last
в измерении времени коротким ответом, который я могу принять? Это может помочь другим, спасибо - person VH-NZZ   schedule 03.07.2014scanl1 (+)
. - person Ørjan Johansen   schedule 03.07.2014sum $ take (length x) x
- person genisage   schedule 03.07.2014