Excel-生成每行三组数字的笛卡尔积
我有一行数据,格式如下: 集合1(仅包含一个数字)|集合2(在唯一单元格中包含1-6个数字)|集合3(在唯一单元格中包含1-6个数字| 示例:[1]|[1][2][3]|[1][5]Excel-生成每行三组数字的笛卡尔积,excel,excel-formula,cartesian-product,vba,Excel,Excel Formula,Cartesian Product,Vba,我有一行数据,格式如下: 集合1(仅包含一个数字)|集合2(在唯一单元格中包含1-6个数字)|集合3(在唯一单元格中包含1-6个数字| 示例:[1]|[1][2][3]|[1][5] 输出:1 1 1,1 1 5,1 2 1,1 2 5,1 3 1,1 3 5这里有一个VBA函数,可以处理3个数字集的特殊情况: Function CartesianProduct(nums1 As Range, nums2 As Range, nums3 As Range) As Variant Dim
输出:1 1 1,1 1 5,1 2 1,1 2 5,1 3 1,1 3 5这里有一个VBA函数,可以处理3个数字集的特殊情况:
Function CartesianProduct(nums1 As Range, nums2 As Range, nums3 As Range) As Variant
Dim n As Long 'number of products
Dim i As Long, j As Long, k As Long, r As Long
Dim products As Variant
n = nums1.Cells.Count * nums2.Cells.Count * nums3.Cells.Count
ReDim products(1 To n, 1 To 3)
For i = 1 To nums1.Cells.Count
For j = 1 To nums2.Cells.Count
For k = 1 To nums3.Cells.Count
r = r + 1 'current row
products(r, 1) = nums1.Cells(i)
products(r, 2) = nums2.Cells(j)
products(r, 3) = nums3.Cells(k)
Next k
Next j
Next i
CartesianProduct = products
End Function
这可以从另一个VBA函数或子函数调用,或直接用作工作表中的数组公式:
在上面的截图中,我选择了A3:C8范围(需要提前确定其大小)输入公式
=CartesianProduct(A1,B1:D1,E1:F1)
然后通过使用Ctrl+Shift+Enter
输入它,将其作为数组公式接受
一旦超过三个集合,事情就会变得有点棘手,因为对于循环方法,你不能在必要的层次上硬连线,而可能会使用递归方法,类似于下面的回答:这是一个函数,可以对任意数量的维度进行笛卡尔积-每个维度的值必须是li垂直放置时,一个维度可能有多个列(请参见下面的示例): 示例(请注意,第一个标注有两列):
请解释所需的输出。即使您使用的是“排列”一词,我怀疑您可能是指其他内容。对于上面的示例:[1]|[1][2][3]|[1][5]输出:1 11,1 15,1 2 1,1 2 5,1 3 1,1 3 5我有一种感觉,我可能是指组合。实际上,我怀疑你指的是更像笛卡尔积的东西,而不是排列或组合。如果你编辑你的问题以显示预期的输出,那会有所帮助。编辑。我没听说过这个!谢谢你帮助我我回答了这个问题。谢谢你,约翰。效果非常好!感谢你的帮助。学习新东西总是很棒的。
Function CartesianProduct(ParamArray range() As Variant) As Variant
Dim n As Long 'number of products
Dim total_dimensions As Long, i As Long, num_dim As Long, num_col As Long, max_cols As Long
Dim dim_sizes As Variant
Dim dim_counters As Variant
Dim products As Variant
ReDim dim_sizes(LBound(range) To UBound(range))
ReDim dim_counters(LBound(range) To UBound(range))
n = 1
max_cols = 0
For i = LBound(range) To UBound(range)
dim_sizes(i) = range(i).Rows.Count
max_cols = max_cols + range(i).Columns.Count
n = n * dim_sizes(i)
dim_counters(i) = 1
Next
ReDim products(1 To n, 1 To max_cols)
For i = 1 To n
carry_one = True
num_col = max_cols
For num_dim = UBound(range) To LBound(range) Step -1
For j = range(num_dim).Columns.Count To 1 Step -1
products(i, num_col) = range(num_dim).Cells(dim_counters(num_dim), j)
num_col = num_col - 1
Next j
If carry_one = True Then
dim_counters(num_dim) = dim_counters(num_dim) + 1
If dim_counters(num_dim) > dim_sizes(num_dim) Then
dim_counters(num_dim) = 1
carry_one = True
Else
carry_one = False
End If
End If
Next num_dim
Next i
CartesianProduct = products
End Function