Forum Webscript.Ru

Программирование => Perl => Тема начата: Phoinix от 09 Августа 2004, 18:09:11

Название: Поиск соответсвия в двух массивах
Отправлено: Phoinix от 09 Августа 2004, 18:09:11
Есть два массива, и нужно узнать сколько в них есть одинаковых элементов, возможно ли это вычислить проще чем

my @arr1 = (\'1\',\'2\',\'3\',\'4\',\'5\');
my @arr2 = (\'6\',\'1\',\'7\',\'5\',\'8\');
my $i;
foreach my $value (@arr2) {$i += grep{/$value/}@arr1}
print $i;
 

результат: 2

?
Название: Поиск соответсвия в двух массивах
Отправлено: КшЫуфксрук от 09 Августа 2004, 20:24:09
Один из массивов (желательно короткий) загнать в хеш, потом пробежаться по второму массиву.
Название: Поиск соответсвия в двух массивах
Отправлено: Phoinix от 09 Августа 2004, 22:01:14
КшЫуфксрук

Цитировать
...загнать в хеш...


Гм... а собственно зачем?

В общем-то а могу сразу формировать один из массивов в хеш (правда определить какой больше - не получится).

Тогда получается конструкция:

my @arr1 = (\'1\',\'2\',\'3\',\'4\',\'5\');
my %hash = {6 => 6, 1 => 1, 7 => 7, 5 => 5, 8 => 8};
my $i;
foreach my $value (@arr1) {$i++ if $hash{$value}}
print $i;


Но насколько это оптимальней?
Название: Поиск соответсвия в двух массивах
Отправлено: КшЫуфксрук от 09 Августа 2004, 22:37:06
Цитировать
Гм... а собственно зачем?


1. Так правильнее. Вот этот код тоже два выдает:


my @arr1 = (\'11\',\'2\',\'3\',\'4\',\'5\');
my @arr2 = (\'6\',\'1\',\'7\',\'5\',\'8\');
my $i;
foreach my $value (@arr2) {$i += grep{/$value/}@arr1}
print $i;


2. Есть подозрение, что на больших массивах будет гораздо быстрее.
Название: Поиск соответсвия в двух массивах
Отправлено: Phoinix от 10 Августа 2004, 10:15:35
КшЫуфксрук

Цитировать
Вот этот код тоже два выдает


Он выдает потому-что 11 ~ /1/, просто не поставил границы:

grep{/^$value$/}@arr1

Поэтому утверждение:

Цитировать
Так правильнее


Не совсем верно...

Цитировать
Есть подозрение, что на больших массивах будет гораздо быстрее


У меня вообщем-то предполагается, что размеры массивов не более 20 элементов каждый. Но для дальнейшего использования интересно получить более оптимально решение...
Основная цель - уйти от цикла (foreach).
Название: Поиск соответсвия в двух массивах
Отправлено: NeoNox от 10 Августа 2004, 11:40:01
Phoinix держи:

map { push (@m , $_) if $_{$_} > 1} grep{!$_{$_}++} @arr1, @arr2;
print $#m+1;

пояснять нужно?
Название: Поиск соответсвия в двух массивах
Отправлено: AnnA от 10 Августа 2004, 11:45:38
Цитировать
Phoinix:
могу сразу формировать один из массивов в хеш

приветик. :)
если это будет хэш %h:
foreach (@arr) { $h{$_}=1; }
print scalar keys %h;
Цитировать
Phoinix:
нужно узнать сколько в них есть одинаковых элементов
Название: Поиск соответсвия в двух массивах
Отправлено: AnnA от 10 Августа 2004, 11:47:14
NeoNox, «монстрите», как всегда. :)
поясните, пож-ста.
Название: Поиск соответсвия в двух массивах
Отправлено: КшЫуфксрук от 10 Августа 2004, 11:56:03
Phoinix
Для 20 элементов наверное нет особой разницы, как делать. Просто твой алгоритм крадратичный, а мой линейный. И зачем уходить от foreach не понятно.

NeoNox
Этот код работает немного не так, как исходный:

my @arr1 = (\'1\',\'2\',\'2\',\'4\',\'5\');
my @arr2 = (\'6\',\'1\',\'7\',\'5\',\'8\');

map { push (@m , $_) if $_{$_} > 1} grep{!$_{$_}++} @arr1, @arr2;
print $#m+1;

выдает "3", а исходный выдал бы "2".
Название: Поиск соответсвия в двух массивах
Отправлено: NeoNox от 10 Августа 2004, 11:56:48
Цитировать
AnnA:
поясните, пож-ста.

запросто.
1. grep{!$_{$_}++} @arr1, @arr2;
здесь формируется временный хеш и ему присваивается количество совпадений
2. map { push (@m , $_) if $_{$_} > 1}
а здесь при совпадении условия $_{$_} > 1 (нам нужно количество неуникальных элементов) заносим в третий массив.

Правда одно но:
мы грепаем по всем спискам, так что если будут совпадения в рамках одного массива - они тоже поместятся в @m.
Название: Поиск соответсвия в двух массивах
Отправлено: Phoinix от 10 Августа 2004, 15:55:51
NeoNox

Да уж... про повторы, я то и забыл, что можно просто вычислить количество совпадений, тем более, что элементы обоих массивов уникальны...

А тема как раз недавно поднималась... http://forums.webscript.ru/showthread.php?s=&postid=111769#post111769 (http://forums.webscript.ru/showthread.php?s=&postid=111769#post111769)

Спасибо...