使用Functional Swift的Fibonacci项的和
我正在尝试学习函数
Swift并开始从Project Euler做一些练习.
根据WWDC高级Swift视频实现了一个memoized斐波那契函数: func memoize<T:Hashable,U>( body: ((T)->U,T) -> U) -> (T)->U { var memo = [T:U]() var result: ((T)->U)! result = { x in if let q = memo[x] { return q } let r = body(result,x) memo[x] = r return r } return result } let fibonacci = memoize { (fibonacci:Int->Double,n:Int) in n < 2 ? Double(n) : fibonacci(n-1) + fibonacci(n-2) } 并实现了一个符合Sequence协议的类 class FibonacciSequence: SequenceType { func generate() -> GeneratorOf<Double> { var n = 0 return GeneratorOf<Double> { fibonacci(n++) } } subscript(n: Int) -> Double { return fibonacci(n) } } 问题的第一个(非功能性)解决方案: var fib = FibonacciSequence().generate() var n:Double = 0 var sum:Double = 0 while n < Double(4_000_000) { if n % 2 == 0 { sum += n } n = fib.next()! } println(sum) 第二个更实用的解决方案,使用ExSwift的takeWhile功能 let f = FibonacciSequence() println((1...40).map { f[$0] } .filter { $0 % 2 == 0 } .takeWhile { $0 < 4_000_000 } .reduce(0,combine: +)) 我想改进这个解决方案,因为乞讨的1 … 40范围无缘无故地计算了太多的术语.理想情况下,我希望能够拥有某种无限范围,但同时只计算满足条件的所需条款 有什么建议 ? 解决方法
有一个filter()函数,它接受一个序列作为参数:
func filter<S : SequenceType>(source: S,includeElement: (S.Generator.Element) -> Bool) -> [S.Generator.Element] 但由于返回值是一个数组,如果你愿意,这不适合 lazy(FibonacciSequence()).filter ( { $0 % 2 == 0 }) 你得到了一个偶数斐波纳契数的“无限”序列.你不能 TakeWhileSequence( lazy(FibonacciSequence()).filter ( { $0 % 2 == 0 }),{ $0 < 4_000_000 } ) 工作并给出所有偶数斐波纳契数的序列小于 let sum = reduce(TakeWhileSequence( lazy(FibonacciSequence()).filter ( { $0 % 2 == 0 }),{ $0 < 4_000_000 }),+) 给出预期结果并仅计算“必要” 请注意,实际上不需要记住Fibonacci数字 struct FibonacciSequence : SequenceType { func generate() -> GeneratorOf<Int> { var current = 1 var next = 1 return GeneratorOf<Int>() { let result = current current = next next += result return result }; } } 而上述计算仍然有效. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |