2012-06-11 30 views
13

Khi lập trình bằng Java (hoặc bất kỳ ngôn ngữ thủ tục nào khác cho vấn đề đó), tôi thường chọn giữa giải quyết một cách đệ quygiải quyết nó lặp đi lặp lại. Tùy chọn đệ quy thường thanh lịch hơn so với giải pháp lặp nên tôi thường tìm giải pháp đệ quy. Với một ngoại lệ:Ok để có độ sâu ngăn xếp tuyến tính tỷ lệ thuận với một số kích thước đầu vào?

Lo lắng về tràn ngăn xếp Tôi có xu hướng tránh các giải pháp đệ quy nếu độ sâu ngăn xếp tối đa tỷ lệ thuận với kích thước đầu vào (hoặc tệ hơn). Tuy nhiên, tôi nhận ra rằng trong nhiều ngôn ngữ khác (ngay cả những ngôn ngữ nhắm vào JVM như Scala và Clojure) nhiều thuật toán, chẳng hạn như các thuật toán danh sách cơ bản, thường được biểu diễn một cách đệ quy nơi độ sâu stack tối đa tỉ lệ với độ dài của danh sách. (1) Vì vậy, là những lo lắng của tôi về việc tràn ngăn xếp trong các thuật toán xếp chồng-chiều sâu-tuyến tính hợp lý?

TL; DR: "Độ phức tạp chiều sâu ngăn xếp" được coi là hợp lý? Logarit phức tạp, tìm kiếm nhị phân đệ quy Ví dụ, O (log N) chắc chắn là ok, nhưng làm thế nào về O (N), O (N log N), O (N)? Bạn thường vẽ đường ở đâu? (2)

(1) Tôi nhận ra rằng ngôn ngữ như vậy đôi khi hỗ trợ những thứ như @tailrec, nhưng câu hỏi này liên quan đến Java, C#, vv
(2) Lưu ý rằng tôi không quan tâm đến CPU overhead vv Chỉ cần chiều sâu ngăn xếp.

+0

Độ phức tạp của độ sâu ngăn xếp là một điều cần xem xét, nhưng một điều khác là kích thước đầu vào chính nó. Nếu vấn đề không bao gồm đầu vào lớn của miền của nó (trong khoảng thời gian kéo dài trong quá trình phát triển), thì chúng ta có thể đi cho giải pháp đệ quy (với giả định độ phức tạp không vượt quá dung lượng của chồng). Nếu kích thước đầu vào không được xác định, độ sâu ngăn xếp O (1) hoặc O (log N) là IMO chấp nhận được (O (log N) có thể không chấp nhận được nếu giới hạn trên ** thực ** trên kích thước đầu vào thậm chí bị hỏng kích thước ngăn xếp, nhưng tôi nghĩ trường hợp này sẽ khá hiếm). – nhahtdh

+1

"Tùy chọn đệ quy thường thanh lịch hơn là giải pháp lặp" Trong 90% trường hợp tôi thấy ngược lại. Nó có thể phụ thuộc vào loại vấn đề bạn đang cố gắng giải quyết và kiểu nào bạn cảm thấy thoải mái hơn. ;) Tôi thường cảm thấy thoải mái với độ sâu đệ quy o (log N). –

+0

Đây có phải là [thẻ: ngôn ngữ thuyết bất khả tri] –

Trả lời

1

Bạn không thể trả lời câu hỏi này mà không tự hỏi mình nhập kích thước nào bạn muốn có thể hỗ trợ.

Độ phức tạp của không gian tuyến tính trên ngăn xếp hoàn toàn ổn nếu bạn đang xử lý một cỗ bài chơi và có thể hoàn toàn vô vọng nếu bạn đang dùng các tệp văn bản lớn. Bạn cần phải tìm ra kích thước đầu vào tối đa cho ứng dụng của bạn, hay đúng hơn, đầu vào lớn nhất mà bạn không quan tâm đến nó không thành công.

Chúng tôi làm việc này mọi lúc. Ví dụ, mỗi khi bạn khai báo một mảng trong Java, bạn biết rằng mảng không thể có nhiều hơn 2 các phần tử trong đó. Điều đó có quan trọng không? Điều đó có nghĩa là chương trình bị hỏng? Chắc là không; nhưng đôi khi nó có, nếu đầu vào lớn là một cái gì đó bạn muốn để có thể đối phó với.

Vì vậy, tôi không nghĩ bạn có thể quá chi tiết về điều này.Bạn sẽ nói gì nếu có ai đó hỏi (theo các thuật ngữ khá chung chung) thời gian phức tạp là gì? Bạn có thể nói một số nguyên tắc chung: thường là tuyến tính là OK, thường là mũ là xấu ... nhưng câu trả lời thực sự là, nó phụ thuộc vào những gì bạn đang làm.

2

Độ phức tạp của độ sâu ngăn xếp là một điều cần cân nhắc, nhưng một thứ khác là chính kích thước đầu vào.

Nếu vấn đề loại trừ đầu vào lớn của miền (đối với mở rộng thời gian trong quá trình phát triển), thì chúng ta có thể đi giải pháp đệ quy (tất nhiên, giải pháp đệ quy không được vượt quá dung lượng của ngăn xếp với đầu vào lớn nhất có thể).

Nếu kích thước đầu vào không được xác định, O (1) chiều sâu ngăn xếp hoặc độ sâu ngăn xếp O (log N) là chấp nhận được, IMHO. Có thể là O (log N) có thể không được chấp nhận nếu giới hạn trên thực tế trên kích thước đầu vào là lớn về mặt thiên văn mà nó vượt quá khả năng ngăn xếp. Tuy nhiên, tôi nghĩ trường hợp như vậy sẽ khá hiếm.

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