2009-11-17 77 views
20

Tôi đã tìm thấy this page mô tả một số thuật toán để tính giai thừa. Thật không may, các giải thích là terse và tôi không cảm thấy như chọn lọc thông qua dòng sau khi dòng mã nguồn để hiểu các nguyên tắc cơ bản đằng sau các thuật toán.Thuật toán nhanh để tính toán giai thừa

Ai có thể chỉ cho tôi mô tả chi tiết hơn về các thuật toán (hoặc nhanh khác) này để tính toán giai thừa?

Chỉnh sửa:This page mô tả phương pháp chính yếu tố, kỹ thuật phổ biến cho tất cả các thuật toán giai thừa hiệu quả nhất. Nó cũng chứa một số mã ví dụ đẹp trong Python. Tác giả liên kết đến a description of binary splitting và tham khảo một bài viết trong Tạp chí thuật toán ("Về tính phức tạp của tính toán các giai thừa") có vẻ đầy hứa hẹn, nếu tôi chỉ có thể có được bàn tay của tôi trên đó.

+4

Nếu giai thừa của bạn lớn và bạn muốn có xấp xỉ, đừng quên xấp xỉ Stirling. Tôi nhận thấy nó không được đề cập trong trang đó. http://en.wikipedia.org/wiki/Stirling%27s_approximation – Rooke

+1

@Rooke: Tôi đang tìm cách tính các giai thừa lớn một cách chính xác ... có lẽ tôi nên rõ ràng hơn trong câu hỏi của mình. Nhờ đề nghị mặc dù! – ThisSuitIsBlackNot

+0

Bạn cũng có thể thử tôi [Nhanh chính xác bigint giai thừa] (https://stackoverflow.com/a/18333853/2521214) – Spektre

Trả lời

9

Khám phá số này paper (PDF link) bởi Richard Fateman. Các mẫu mã có trong Lisp, nhưng trong bất kỳ trường hợp nào, phần lớn các bí mật đều được giảm xuống để giảm thiểu số lượng các phép tính bignum (số nguyên chính xác tùy ý) mà bạn phải thực hiện.

Đương nhiên, nếu bạn không cần/có bignums, nó tầm thường; hoặc một bảng tra cứu hoặc một vòng lặp đơn giản sẽ được sử dụng tốt.

EDIT: Nếu bạn có thể sử dụng một câu trả lời gần đúng, bạn có thể tính toán logarit của giai thừa trực tiếp bằng cách tổng hợp log(k) cho k = 2 ... n, hoặc bằng cách sử dụng kính Stirling approximation. Bạn muốn làm việc với logarit bất cứ nơi nào có thể để tránh tràn; đặc biệt, một ứng dụng ngây thơ của xấp xỉ Stirling sẽ tràn vào rất nhiều nơi mà nó không phải.

+0

+1: giấy đó là rất hữu ích (mặc dù Lisp của tôi là một chút gỉ). Thật không may, có vẻ như Luschny là người đi đến các thuật toán phức tạp hơn, vì vậy tôi có thể bị kẹt đọc qua mã nguồn của anh ấy. – ThisSuitIsBlackNot

4

Ngoài ra còn có một phương pháp khác. Phương pháp này được mô tả chi tiết here làm giảm một nửa số phép nhân cho một chút phép cộng và trừ. Bạn có thể muốn phương pháp đầu tiên được hiển thị và phương pháp thứ hai được hiển thị là một cách đọc thú vị nếu bạn có thể hiểu được.

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