Cám ơn bạn@HieuCD:
Theo lý thuyết thì lời giải chỉ cần mảng 1 chiều. Có lẽ vì lý do cần chuyển kết quả lên worksheet mà bạn phải dùng mảng 2 chiều. Điều này tuy hiệu quả nhưng rất gượng ép và làm giảm tính chất độc lập của cái hàm chính - tức là cái hàm tính tổ hợp của bạn. Nói cách khác, người đọc code hàm HoanVi sẽ thắc mắc không hiểu tại sao trong hàm lại dùng mảng 2 chiều; mãi đến lúc đọc code hàm GPE mới hiểu.
Nếu là tôi thì tôi cho hàm chính chạy trên mảng 1 chiều. Khi cần hiển thị lên worksheet thì chuyển qua mảng 2 chiều.
Dùng code sửa từ code nguyên thủy của bạn thì thời gian chuyển qua mảng 2 chiều chỉ bằng 1/4 thời gian đưa lên bảng tính. Tổng cộng lại, kết quả chỉ chậm hơn code nguyên thủy khoảng 10%.
Mã:Sub GPE() Dim Arr(), Str As String t = Timer Str = "123456789" HoanVi Str, Arr [c1] = Timer - t ' cái này mới là thời gian tính thực thụ Dim Arr2, i As Long, sd As Long sd = UBound(Arr) ReDim Arr2(1 To sd, 1 To 1) For i = 1 To sd Arr2(i, 1) = Arr(i) Next i [a1].Resize(sd) = Arr2 [b1] = Timer - t End Sub Private Sub HoanVi(ByVal Str As String, Arr()) Dim n As Long, q As Long, m As Long Dim i As Byte, j As Byte, k As Byte, S As Byte S = Len(Str) ReDim Arr(1 To WorksheetFunction.Fact(S)) Arr(1) = Str: n = 1 For k = 2 To S q = n: n = n * k For i = 1 To k - 1 For m = 1 To n \ k q = q + 1 Arr(q) = Str Mid(Arr(q), i, 1) = Mid(Str, k, 1) Mid(Arr(q), i + 1, k - i) = Mid(Arr(m), i, k - i) If i > 1 Then Mid(Arr(q), 1, i - 1) = Mid(Arr(m), 1, i - 1) Next m Next i Next k End Sub
Mình chỉnh lại biến hợp lý hơn
Mã:
Private Sub HoanVi(ByVal Str As String, Arr())
Dim n As Long, q As Long, m As Long
Dim i As Byte, j As Byte, k As Byte, S As Byte
S = Len(Str)
ReDim Arr(1 To WorksheetFunction.Fact(S))
q = 1: n = 1
Arr(q) = Str
For k = 2 To S
n = n * (k - 1) 'So kha nang cua Hoan Vi bac k-1
For i = 1 To k - 1
For m = 1 To n
q = q + 1
Arr(q) = Str
Mid(Arr(q), i, 1) = Mid(Str, k, 1)
Mid(Arr(q), i + 1, k - i) = Mid(Arr(m), i, k - i)
If i > 1 Then Mid(Arr(q), 1, i - 1) = Mid(Arr(m), 1, i - 1)
Next m
Next i
Next k
End Sub