我正在处理Excel工作表,我需要确定大小为N的垂直数组的奇偶校验。数组包含从1到N的每个数字,每个数字恰好一次。
在此上下文中,奇偶校验定义为将加扰数组从最小到最大转换为排序数组所需的交换次数。
例如,数组{3;1;2;4}
具有偶数奇偶校验,因为它需要两次交换(至少)转换为{1;2;3;4}
,但总是需要偶数个交换。见下文。
3 --> 1 1
1 --> 3 --> 2
2 2 --> 3
4 4 4
另一个例子:{2;1;4;5;3}
有奇数奇偶校验,因为它需要三次交换(至少)转换为{1;2;3;4;5}
,但总是需要奇数个交换。见下文。
2 --> 1 1 1
1 --> 2 2 2
4 4 --> 3 3
5 5 5 --> 4
3 3 --> 4 --> 5
我正在寻找一种解决方案,它可以为具有偶校验的数组返回TRUE
,为奇数奇偶校验的数组返回FALSE
。 (而且我不关心对于不包含从1到N的所有数字的数组的结果是什么,因为我在电子表格中有其他检查来处理这些情况。)
我已经找到了一个使用几个辅助列的解决方案,但它似乎是一个缓慢的计算。
我这样做是通过检查数组中的每个单独的数字是否在正确的索引中,如果它没有执行交换。然后我总结了发生的掉期数量并使用MOD(<swaps>,2)=0
来确定它是否是偶数奇偶校验。
有关数组{8;5;3;2;4;1;7;6}
的示例计算,请参见下文。
我对单元格进行了颜色编码,以便轻松分辨出发生了什么:
白色=参考数组{1;2;3;4;5;6;7;8}
蓝色=输入数组
Gray =“helper”数组,其中每个连续列在必要时执行交换
红色=表示是否从上一列发生了交换
如果在该列中发生交换,则绿色= 1;如果未发生交换,则为0
黄色=所有绿色单元格的总和,有效地告知发生了多少交换。
在该示例中,由于黄色单元是4
,其是偶数,所以输入阵列具有偶数奇偶校验。
问题是:如果没有VBA,可以在Excel中更有效地完成此计算吗?我不一定反对帮助列,但再次看来我的解决方案似乎很迟钝,我想知道是否有更好的方法。
我想如果没有辅助列,我有办法做到这一点!
首先,我将向您展示一个使用N辅助列的方法,然后我将展示如何使用数组公式。考虑下面的矩阵显示:
绿色范围是指数,蓝色范围是您的排列。黄色矩阵是您在公式框中定义的permutation matrix。
你的排列的奇偶性与该矩阵的行列式的值相同!
幸运的是,Excel有一个内置的决定性函数MDETERM()
。偶数置换具有奇偶校验1,奇数置换具有奇偶校验-1,因此您可以使用公式简单地得到行列式
=MDETERM(C2:J9)
现在这很酷,但真正的踢球者是我们甚至不需要制作那个矩阵。我们可以在这样的数组公式中构造它:
{=MDETERM(IF(B2:B9=TRANSPOSE(A2:A9),1,0))}
这里我们只使用A列和B列!此版本中未使用C:J列。
(请注意,这是一个数组公式,因此您需要使用Ctrl + Shift + Enter来验证它。这将围绕公式包围大括号。不要手动执行此操作。)