Автор Тема: Поиск соответсвия в двух массивах  (Прочитано 4871 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Phoinix

  • RW
  • Ветеран
  • *****
  • Сообщений: 1097
  • +0/-0
  • 2
    • Просмотр профиля
    • http://phoinix.ucoz.ru
Поиск соответсвия в двух массивах
« : 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

?

Оффлайн КшЫуфксрук

  • Завсегдатай
  • Пользователь
  • **
  • Сообщений: 99
  • +0/-0
  • 0
    • Просмотр профиля
    • http://risearch.org/
Поиск соответсвия в двух массивах
« Ответ #1 : 09 Августа 2004, 20:24:09 »
Один из массивов (желательно короткий) загнать в хеш, потом пробежаться по второму массиву.

Оффлайн Phoinix

  • RW
  • Ветеран
  • *****
  • Сообщений: 1097
  • +0/-0
  • 2
    • Просмотр профиля
    • http://phoinix.ucoz.ru
Поиск соответсвия в двух массивах
« Ответ #2 : 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;


Но насколько это оптимальней?

Оффлайн КшЫуфксрук

  • Завсегдатай
  • Пользователь
  • **
  • Сообщений: 99
  • +0/-0
  • 0
    • Просмотр профиля
    • http://risearch.org/
Поиск соответсвия в двух массивах
« Ответ #3 : 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

  • RW
  • Ветеран
  • *****
  • Сообщений: 1097
  • +0/-0
  • 2
    • Просмотр профиля
    • http://phoinix.ucoz.ru
Поиск соответсвия в двух массивах
« Ответ #4 : 10 Августа 2004, 10:15:35 »
КшЫуфксрук

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


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

grep{/^$value$/}@arr1

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

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


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

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


У меня вообщем-то предполагается, что размеры массивов не более 20 элементов каждый. Но для дальнейшего использования интересно получить более оптимально решение...
Основная цель - уйти от цикла (foreach).

Оффлайн NeoNox

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3012
  • +0/-0
  • 0
    • Просмотр профиля
Поиск соответсвия в двух массивах
« Ответ #5 : 10 Августа 2004, 11:40:01 »
Phoinix держи:

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

пояснять нужно?
The documentations is your friend

Оффлайн AnnA

  • Фанатка форума
  • Старожил
  • ****
  • Сообщений: 263
  • +0/-0
  • 2
    • Просмотр профиля
    • http://
Поиск соответсвия в двух массивах
« Ответ #6 : 10 Августа 2004, 11:45:38 »
Цитировать
Phoinix:
могу сразу формировать один из массивов в хеш

приветик. :)
если это будет хэш %h:
foreach (@arr) { $h{$_}=1; }
print scalar keys %h;
Цитировать
Phoinix:
нужно узнать сколько в них есть одинаковых элементов
пока-пока. :)

Оффлайн AnnA

  • Фанатка форума
  • Старожил
  • ****
  • Сообщений: 263
  • +0/-0
  • 2
    • Просмотр профиля
    • http://
Поиск соответсвия в двух массивах
« Ответ #7 : 10 Августа 2004, 11:47:14 »
NeoNox, «монстрите», как всегда. :)
поясните, пож-ста.
пока-пока. :)

Оффлайн КшЫуфксрук

  • Завсегдатай
  • Пользователь
  • **
  • Сообщений: 99
  • +0/-0
  • 0
    • Просмотр профиля
    • http://risearch.org/
Поиск соответсвия в двух массивах
« Ответ #8 : 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

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3012
  • +0/-0
  • 0
    • Просмотр профиля
Поиск соответсвия в двух массивах
« Ответ #9 : 10 Августа 2004, 11:56:48 »
Цитировать
AnnA:
поясните, пож-ста.

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

Правда одно но:
мы грепаем по всем спискам, так что если будут совпадения в рамках одного массива - они тоже поместятся в @m.
The documentations is your friend

Оффлайн Phoinix

  • RW
  • Ветеран
  • *****
  • Сообщений: 1097
  • +0/-0
  • 2
    • Просмотр профиля
    • http://phoinix.ucoz.ru
Поиск соответсвия в двух массивах
« Ответ #10 : 10 Августа 2004, 15:55:51 »
NeoNox

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

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

Спасибо...

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28