作为我想要的等效简化示例,这个工作表中包含5个数字的任意序列,每个数字在1-9之间,从A列到E列以及许多行:
| A| B| C| D| E|
1 | 1| 5| 6| 8| 9|
2 | 2| 5| 7| 8| 9|
...
50| 1| 3| 4| 6| 7|
然后我想检查所有行中每行出现的任意两个数字的组合数,并用结果填充组合数组:
| 1| 2| 3| 4| 5| 6| 7| 8| 9|
1| | | | | | | | | |
2| | | | | | | | | |
3| | | | | | | | | |
4| | | | | | | | | |
5| | | | x| | | | | |
6| | | | | | | | | |
7| | | | | | | | | |
8| | | | | | | | | |
9| | | | | | | | | |
在上面,“x”表示数字4和5的组合中出现的行数。
我通过VBA代码轻松实现了我的目标,但想通过excel-formula知道如何做到这一点,因为它通常会更快。
以防任何人想要检查已经适用于此任务的VBA代码:
Sub NPairs()
Dim Rn As Long
Dim Cn As Long
For Nrow = 2 To 10
For Ncol = 2 To 10
If NCol = NRow Then GoTo NextN 'Skip, cause would search the combination of the same numbers.
Rn = Plan2.Cells(NRow, 1).Value2
Cn = Plan2.Cells(1, NCol).Value2
Plan2.Cells(Nrow, Ncol) = NMatch(Rn, Cn)
NextN:
Next
Next
End Sub
Private Function Nmatch(Rnumber As Long, Cnumber As Long) As Long
Lastrow = Plan1.Cells(Plan1.Rows.Count, "A").End(xlUp).Row
M = 0
For R = 2 To Lastrow
For C = 1 To 5
If Plan1.Cells(R, C).Value2 = Rnumber Then
For Cl = 1 To 5
If Plan1.Cells(R, Cl).Value2 = Cnumber Then M = M + 1
Next
End If
Next
Next
Nmatch = M
End Function
我知道,这可以通过使用数组或字典来固定。我想知道的是,如果可以通过excel-formula以更简单的方式做同样的事情。
答案 0 :(得分:3)
如果您关心的是速度,那么在这种情况下VBA可能会更快。但是这里有一个想法只用公式来做:
创建一个中间矩阵,其中包含与源矩阵一样多的行,并为每个数字创建一列(1 .. 9)。使用公式指示相应的行是否包含列标识的数字。
根据此中间矩阵,查找两个感兴趣的数字为TRUE的行。
如果需要,您可以隐藏中间矩阵。
以下是它的外观:
中间矩阵是中间矩阵。 G2中的公式为:
=COUNTIF($A2:$E2, G$1)
您可以将其复制到该矩阵的其他单元格
最右边的矩阵是最终结果。 R2中的公式为:
=IF(R$1=$Q2, COUNTIFS(INDEX($G$2:$O$9, 0, R$1),">1"),
COUNTIFS(INDEX($G$2:$O$9, 0, R$1),">0", INDEX($G$2:$O$9, 0, $Q2), ">0"))
INDEX
函数用于检索中间矩阵中的相应列。基于当前行(在最终矩阵中)选择中间矩阵中的一列,而另一列基于当前列。两者必须具有值TRUE(在同一行中)才能计算。
在您发表评论之后,我将公式包装在IF
中以处理主对角线的情况:在这种情况下,单个数字必须连续多次出现才能计算后者。< / p>
您可以从Google docs
下载上述表格答案 1 :(得分:0)
=SUM(IF(ISNUMBER(SEARCH("*"&J$1&"*"&$I2&"*",$A$1:$A$50&$B$1:$B$50&$C$1:$C$50&$D$1:$D$50&$E$1:$E$50)),1,IF(ISNUMBER(SEARCH("*"&$I2&"*"&J$1&"*",$A$1:$A$50&$B$1:$B$50&$C$1:$C$50&$D$1:$D$50&$E$1:$E$50)),1,0)))
这是一个数组公式,同时仍在公式栏中按 Ctrl + Shift + Enter
使用带有SEARCH()
的通配符,我们可以查找构建字符串中的数字,然后反转serach顺序以捕获这两个实例。我根据结果构建了一个二进制数组,并SUM()
。
*
等同于任意数量的任何字符(也可以是0个字符)。使用这个我们可以确定2个数字是否出现在5个位置的任何位置,然后翻转以捕获它们是否处于其他顺序。
答案 2 :(得分:0)