Возможно. Похоже, вы можете переформулировать проблему как
Найти все пары ключей K1
и K2
, для которых:
$some_other_hash{K1} == $some_other_hash{K2}
K1
существует в %hash1
, а K2
существует в %hash2
так что давайте попробуем подход, в котором вы сначала найдете решения для первого условия, а затем посмотрим, удовлетворяют ли они второму условию. Итерация по всем парам ключей - это O (n 2 ), но у нас уже есть стратегия для нахождения ключей, которые быстро сопоставляются с тем же значением хеш-функции: используйте другой хеш!
Давайте создадим «обратный хеш» %some_other_hash
, чтобы $hash7{VAL}
создавал список всех ключей в %some_other_hash
, так что $some_other_hash{KEY} == VAL
:
push @{$hash7{ $some_other_hash{$_} }, $_ for keys %some_other_hash;
Это была операция O (n). Затем нам нужно найти значения, которые соответствуют нескольким ключам.
foreach my $v (keys %hash7) {
@k = @{$hash7{$v}};
next if @k < 2;
...
}
Если вы найдете такое значение, проверьте, находятся ли некоторые ключи в %hash1
, а некоторые в %hash2
.
foreach my $v (keys %hash7) {
@k = @{$hash7{$v}};
next if @k < 2;
@k1 = grep { exists $hash1{$_} } @k;
@k2 = grep { exists $hash2{$_} } @k;
if (@k1 && @k2) {
foreach my $k1 (@k1) {
foreach my $k2 (@k2) {
print "$k1 from %hash1 and $k2 from %hash2 ",
"have the same value $v in %some_other_hash\n";
...
}
}
}
}
В худшем случае, когда в %some_other_hash
обычно встречаются значения, которые отображаются более чем одним ключом, этот цикл равен O (mn). В зависимости от ваших данных этот поиск может быть значительно быстрее, чем итерация по всем парам ключей в %hash1
и %hash2
.