Nó thực sự không rõ ràng những gì bạn đang yêu cầu. Nó có thể là một trong vài điều khác nhau. Đầu tiên sẽ là sự kết hợp đơn giản của các yếu tố khác nhau trong một danh sách. Scala cung cấp phương thức combinations()
từ các bộ sưu tập. Nếu các phần tử là khác biệt, hành vi chính xác là những gì bạn mong đợi từ định nghĩa cổ điển của "kết hợp". Đối với kết hợp phần tử n của các phần tử p sẽ có p!/N! (P-n)! kết hợp trong đầu ra.
Nếu có các yếu tố lặp lại trong danh sách, tuy nhiên, Scala sẽ tạo kết hợp với mục xuất hiện nhiều lần trong các kết hợp. Nhưng chỉ các kết hợp có thể khác nhau, với phần tử có thể được sao chép nhiều lần khi chúng tồn tại trong đầu vào. Nó chỉ tạo ra tập hợp các kết hợp có thể, do đó các phần tử được lặp lại, nhưng không phải là các kết hợp lặp lại. Tôi không chắc chắn nếu cơ bản nó có một iterator đến một thực tế Set
. Bây giờ điều bạn thực sự muốn nói nếu tôi hiểu chính xác là các kết hợp từ một tập hợp các phần tử p khác nhau, trong đó phần tử có thể xuất hiện nhiều lần n lần trong tổ hợp.
Vâng, quay lại một chút, để tạo kết hợp khi có các yếu tố lặp lại trong đầu vào và bạn muốn xem kết hợp lặp lại trong đầu ra, cách để thực hiện nó là tạo ra nó bằng "brute-force "sử dụng n vòng lặp lồng nhau. Lưu ý rằng thực sự không có gì xấu về nó, nó chỉ là số kết hợp tự nhiên, thực sự, đó là O (p^n) cho n nhỏ, và không có gì bạn có thể làm về nó. Bạn chỉ nên cẩn thận để chọn các giá trị đúng cách, như thế này:
val a = List(1,1,2,3,4)
def comb = for (i <- 0 until a.size - 1; j <- i+1 until a.size) yield (a(i), a(j))
dẫn đến
scala> comb
res55: scala.collection.immutable.IndexedSeq[(Int, Int)] = Vector((1,1), (1,2), (1,3), (1,4), (1,2), (1,3), (1,4), (2,3), (2,4), (3,4))
này tạo ra các kết hợp từ những giá trị này lặp đi lặp lại trong một, bằng cách đầu tiên tạo ra các kết hợp trung gian của 0 until a.size
như (i, j) ...
Bây giờ để tạo "kết hợp với lặp lại", bạn chỉ cần thay đổi các chỉ mục như sau:
val a = List('A','B','C')
def comb = for (i <- 0 until a.size; j <- i until a.size) yield (a(i), a(j))
sẽ sản xuất
List((A,A), (A,B), (A,C), (B,B), (B,C), (C,C))
Nhưng tôi không chắc chắn cách tốt nhất để khái quát này để kết hợp lớn hơn là những gì.
Bây giờ tôi đóng với những gì tôi đang tìm kiếm khi tôi tìm thấy bài đăng này: một hàm để tạo kết hợp từ đầu vào chứa các phần tử lặp lại, với chỉ số trung gian được tạo bởi combinations()
. Nó là tốt đẹp mà phương pháp này tạo ra một danh sách thay vì một tuple, do đó có nghĩa là chúng tôi thực sự có thể giải quyết vấn đề bằng cách sử dụng một "bản đồ của một bản đồ", một cái gì đó tôi không chắc chắn bất cứ ai khác đã đề xuất ở đây, nhưng đó là khá tiện lợi và sẽ làm cho tình yêu của bạn cho FP và Scala phát triển hơn một chút sau khi bạn nhìn thấy nó!
def comb[N](p:Seq[N], n:Int) = (0 until p.size).combinations(n) map { _ map p }
kết quả trong
scala> val a = List('A','A','B','C')
scala> comb(a, 2).toList
res60: List[scala.collection.immutable.IndexedSeq[Int]] = List(Vector(1, 1), Vector(1, 2), Vector(1, 3), Vector(1, 2), Vector(1, 3), Vector(2, 3))
Bạn cũng có thể dán đoạn code về vấn đề, đánh dấu nó như là mã nguồn. –
Vui lòng chỉnh sửa câu hỏi thay vì đăng lại câu hỏi dưới dạng "câu trả lời". –