我需要测试两个数组是否相等,每个数组包含 8 个整数项1..7
。问题是我关心的不是价值观本身,而是价值观的模式。例如:
eq? [ 1,2,3,4, 5,6,7,1 ], [ 1,2,3,4, 7,6,5,1 ] # => true
eq? [ 1,1,2,2, 3,3,4,4 ], [ 3,3,2,2, 1,1,4,4 ] # => true
eq? [ 1,1,1,1, 2,2,2,2 ], [ 1,1,1,2, 1,2,2,2 ] # => false
eq? [ 1,2,1,3, 4,4,5,6 ], [ 7,5,7,6, 2,2,3,4 ] # => true
!编辑示例,因此第一个参数已经标准化
注意:数组中间的空格只是为了便于阅读。
我需要这样做数百万次。所以我想出了以下方法。
# this method "standardizes" permutation 2 before comparing to permutation1 which is assumed to already be standardized
def eq? permutation1, permutation2
next_val = 0
key = Hash.new { |h,k| h[k] = next_val+=1 }
permutation1 == permutation2.map { |i| key[i] }
end
permutation1 将是少数几个值之一,因此可以在测试之前标准化一次,而每个 permutation2 都是唯一的。
但这太慢了!有没有更好的方法来解决这个问题,也许使用相同的方法但避免使用散列作为键?还是完全不同的方法?
编辑:为了澄清一点,如果您可以替换 ONE 数组中的每个数字或数字的子集,则应将两个数组视为相等,以便每个原始数字映射到一个唯一的新数字(即 1 => 3、3 => 4, 4 => 2, 2 => 1 等),然后这两个数组实际上是相同的。因此,重要的不是值(它们可以是七种不同的颜色或单词,就像数字一样容易),而是值的模式。
EDIT2:应用于 3 位数组的原理意味着:
[1,1,1] 匹配所有项目都相同的任何数组,
[1,2,3] 匹配所有项目不同的任何数组,
[1,1,2] 匹配任何前两项相同而第三项不同的数组,
[1,2,1] 匹配第一个相同且第三个但不是第二个的任何数组,
[1,2,2] 匹配第二个和第三个相同但第一个不同的任何数组,
任何三项数组都将匹配这 5 项中的一项。