Mình có nhu cầu tạo danh sách tổ hợp các số. Số lượng khá nhỏ nên tôi có thể sử dụng byte
hơn là int
. Tuy nhiên, nó yêu cầu nhiều vòng lặp lồng nhau để có được mọi kết hợp có thể. Tôi tự hỏi liệu có cách nào hiệu quả hơn để làm những gì tôi đang theo đuổi. Mã cho đến nay là:
var data = new List<byte[]>();
for (byte a = 0; a < 2; a++)
for (byte b = 0; b < 3; b++)
for (byte c = 0; c < 4; c++)
for (byte d = 0; d < 3; d++)
for (byte e = 0; e < 4; e++)
for (byte f = 0; f < 3; f++)
for (byte g = 0; g < 3; g++)
for (byte h = 0; h < 4; h++)
for (byte i = 0; i < 2; i++)
for (byte j = 0; j < 4; j++)
for (byte k = 0; k < 4; k++)
for (byte l = 0; l < 3; l++)
for (byte m = 0; m < 4; m++)
{
data.Add(new [] {a, b, c, d, e, f, g, h, i, j, k, l, m});
}
Tôi đã xem xét sử dụng một cái gì đó giống như một BitArray
nhưng tôi không chắc mình có thể kết hợp nó như thế nào.
Bất kỳ khuyến nghị sẽ được đánh giá rất cao. Ngoài ra, có lẽ đây là cách nhanh nhất để làm những gì tôi muốn?
CHỈNH SỬA Vài điểm nhanh (và xin lỗi tôi đã không đưa những điểm này vào bài viết gốc):
- Các con số và thứ tự của chúng (2, 3, 4, 3, 4, 3, 3, v.v.) rất quan trọng, vì vậy việc sử dụng một giải pháp như Tạo hoán vị bằng LINQ sẽ không hữu ích vì số tối đa trong mỗi 'cột' là khác nhau
- Tôi không phải là nhà toán học, vì vậy tôi xin lỗi nếu tôi không sử dụng các thuật ngữ kỹ thuật như 'hoán vị' và 'kết hợp' một cách chính xác :)
- Tôi làm cần phải cư tất cả các kết hợp cùng một lúc - Tôi không thể chỉ cần lấy một hay cách khác dựa trên một chỉ số
- Sử dụng
byte
nhanh hơn sử dụngint
, tôi đảm bảo điều đó. Việc sử dụng bộ nhớ cũng tốt hơn rất nhiều khi có hơn 67 triệu mảng byte thay vì mảng int - Mục tiêu cuối cùng của tôi ở đây là tìm kiếm một giải pháp thay thế nhanh hơn cho các vòng lặp lồng nhau.
- Tôi đã cân nhắc sử dụng lập trình song song, nhưng do tính chất lặp đi lặp lại của những gì tôi đang cố gắng đạt được, tôi không thể tìm ra cách thực hiện thành công (ngay cả với
ConcurrentBag
) - tuy nhiên tôi rất vui khi được chứng minh là sai :)
PHẦN KẾT LUẬN
Caramiriel đã cung cấp một tối ưu hóa vi mô tốt giúp loại bỏ một số thời gian khỏi các vòng lặp, vì vậy tôi đã đánh dấu câu trả lời đó là đúng. Eric cũng đề cập rằng việc phân bổ trước Danh sách sẽ nhanh hơn. Tuy nhiên, ở giai đoạn này, có vẻ như các vòng lặp lồng nhau trên thực tế là cách nhanh nhất có thể để thực hiện việc này (thật đáng buồn, tôi biết!).
Nếu bạn muốn thử chính xác những gì tôi đang cố gắng làm điểm chuẩn StopWatch
, hãy sử dụng 13 vòng lặp đếm tối đa 4 trong mỗi vòng lặp - điều đó tạo ra khoảng hơn 67 triệu dòng trong danh sách. Trên máy của tôi (i5-3320M 2,6GHz), mất khoảng 2,2 giây để thực hiện phiên bản tối ưu hóa.