Tôi đã viết một bộ tạo hoán vị cho danh sách Scala tạo tất cả các hoán vị của một danh sách nhất định. Cho đến nay, tôi đã có những điều sau dựa trên this Haskell implementation (và tôi nghĩ rằng nó hiệu quả hơn so với một số tùy chọn khác mà tôi đã thử). Có cách nào để làm cho điều này thậm chí hiệu quả hơn, hoặc tôi đã bao trả tất cả các căn cứ của tôi?Máy phát hoán vị nhanh hơn
/** For each element x in List xss, returns (x, xss - x) */
def selections[A](xss:List[A]):List[(A,List[A])] = xss match {
case Nil => Nil
case x :: xs =>
(x, xs) :: (for((y, ys) <- selections (xs))
yield (y, x :: ys))
}
/** Returns a list containing all permutations of the input list */
def permute[A](xs:List[A]):List[List[A]] = xs match {
case Nil => List(Nil)
//special case lists of length 1 and 2 for better performance
case t :: Nil => List(xs)
case t :: u :: Nil => List(xs,List(u,t))
case _ =>
for ((y,ys) <- selections(xs); ps <- permute(ys))
yield y :: ps
}
Điều này có nhanh hơn phương pháp hoán đổi dựa trên mảng không? Hoặc bạn có nghĩa là "máy phát điện hoán vị chức năng nhanh nhất"? (Bạn không bao giờ nói rõ như vậy, nhưng bạn đã thêm thẻ ....) –
Tôi có nghĩa là trình tạo hoán vị chức năng nhanh nhất. Vì lý do đó, chưa thử so sánh điều này với phương thức hoán đổi dựa trên mảng. –
Có các thuật toán tốt hơn. Tôi thấy một ở đây trên Stack Overflow cách đây không lâu, trong Scala, mà trả về hoán vị tiếp theo (giả sử một tập hợp các chỉ số), thay vì một danh sách tất cả các hoán vị. Nó sử dụng 'phân vùng' để tìm điểm của hoán vị chỉ mục tiếp theo, và thường tránh các cuộc gọi đệ quy không đuôi. Ngoài ra, tất nhiên, việc triển khai mã của Haskell mà bạn đã hiển thị sẽ chạy rất nhanh, bởi vì nó sẽ không tính toán bất cứ thứ gì lên phía trước. :-) –