2011-11-11 33 views
6

Tôi đã tự hỏi nếu có một cách tốt hơn để viết các vòng đệ quy trong scala.Làm thế nào để làm các vòng đệ quy trong scala

def fib(n: Int) = { 
    def loop(a: BigInt = 0, b: BigInt = 1, n: Int = n): BigInt = { 
    if(n==0) a 
    else loop(b, a+b, n-1) 
    } 
    loop() 
} 

tôi có thể viết nó như thế này

def fib(n: Int, a: BigInt = 0, b: BigInt = 1): BigInt = { 
    if(n==0) a 
    else fib(n-1, b, a+b) 
} 

nhưng sau đó a và b sẽ được tiếp xúc và không được đóng gói bên trong phương pháp này nữa.

+0

Đó là cách thực hiện khá nhiều (ví dụ đầu tiên). 'Def' bên trong cũng đảm bảo nó là riêng tư và có thể được tối ưu hóa cho đuôi đuôi. – huynhjl

+0

Phiên bản thứ hai là đệ quy đuôi quá. Tôi hỏi về khả năng thêm một số cách để làm cho các thông số này riêng tư trong danh sách gửi thư của Scala Language vào tháng 8 và đã gặp phải một sự im lặng điếc/thiếu sự quan tâm. http://www.scala-lang.org/node/10736 –

+0

Câu trả lời ngắn gọn: Không. –

Trả lời

3

Lưu ý rằng bạn có thể thường xuyên sử dụng foldLeft hoặc foldRight trong tình huống như vậy:

def fib(n: Int) = (1 to n).foldLeft((BigInt(0),BigInt(1)))((p,_)=>(p._2,p._1+p._2))._1 

[Chỉnh sửa]

cách tiếp cận khác sẽ là một giải pháp lặp dựa trên:

def fib = Iterator.iterate((0,1)){case (x,y) => (y,x+y)}.map(_._1) 

Điều này tạo ra số lượng mã số vô hạn, nhưng bạn có thể chỉ cần lấy bao nhiêu tùy thích nó, ví dụ fib.take(10).toList

1

Vòng lặp có phạm vi riêng của chúng. Khi bạn thay thế một vòng lặp với một hàm đệ quy, bạn buộc phải tạo một phạm vi rõ ràng (phương thức bên trong). Không có cách nào xung quanh nó. Đây là cách nó được thực hiện. Không có gì sai về nó.

Các vấn đề liên quan