Автор Тема: Сравнить два массива  (Прочитано 5211 раз)

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

Оффлайн cr4ck3r

  • Фанат Perl
  • Постоялец
  • ***
  • Сообщений: 146
  • +0/-0
  • 2
    • Просмотр профиля
    • http://perlmonks.org.ru
Сравнить два массива
« : 21 Апреля 2005, 11:00:27 »
Что-то я туплю немного. Подскажите как наиболее эффективно решить такую задачу:

Имеется массив со списком имен файлов. Имеется текстовый файл, также со списком имен файлов. Требуется, из массива удалить имена файлов которые встречаются в текстовом файле, и получить в результате список файлов которые не упоминаются в текстовом файле. Что-то я никак не могу найти нужного решения, а точнее наиболее эффективного и быстрого.
Ворота в perl - perlmonks.org.ru

Оффлайн commander

  • Developer
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 1298
  • +0/-0
  • 2
    • Просмотр профиля
    • http://www.webtips.ru
Сравнить два массива
« Ответ #1 : 21 Апреля 2005, 11:14:55 »
cr4ck3r
за тебя весь код написать? приведи хоть код своего, как ты считаешь, не эфективного решения... посмотрим если надо оптимизуруем...
And no religion too...

Оффлайн cr4ck3r

  • Фанат Perl
  • Постоялец
  • ***
  • Сообщений: 146
  • +0/-0
  • 2
    • Просмотр профиля
    • http://perlmonks.org.ru
Сравнить два массива
« Ответ #2 : 21 Апреля 2005, 11:20:35 »
Сори. Забыл.
Код в общем-то еще в очеь черновом варианте, поэтому не пугайтесь некоторых конструкций - они для дебаггинга.
В общем-то тут наверно стоит привести две функции:

sub GetFiles {
my $month=shift;
GetError("Can\'t find downloads directory by path: $CONFIG{\'path\'}") unless(-d $CONFIG{\'path\'});
my $mnum=MonName($month);
my $year=substr($CONFIG{\'year\'},2,2);
$mnum=$year . $mnum;
opendir(DIR,$CONFIG{\'path\'}) || GetError("Can\'t open downloads directory: $!");
my @FILES=grep(!/^\\.\\.?$/,readdir DIR);
@FILES=grep(/^$mnum/,@FILES);
close(DIR);
@FILES=Compare($month,\\@FILES);# сравниваем списки файлов с логами
return @FILES if 1;
}

Здесь важна лишь строчка -> @FILES=Compare($month,\\@FILES);
то есть в функцию передаю список файлов (ссылка на массив)
Теперь код функции Compare:

sub Compare {
my $mon=shift;
my $files=shift;# ссылка на массив @FILES
return @{$files} unless(-e "./lib/data/$mon$CONFIG{\'year\'}.txt");# возвращаем полный список - если файла нет
open(LIST,"<","./lib/data/$mon$CONFIG{\'year\'}.txt")|| GetError("Can\'t open data file $mon$CONFIG{\'year\'}: $!");
my @LIST=;
close(LIST);
### вот он уже десятый вариант кода... этот кусок самый тупой... ##########
my($i,$y);
for($i=0;$i<=scalar @{$files};$i++) {
   for($y=0;$y<=scalar @LIST; $y++) {
      shift @{$files} if($files->[$i] eq $LIST[$y]);
      }
   }
#############################
return @{$files};      
}


В общем-то я пришел к самому идиотскому варианту... как видите.
Ворота в perl - perlmonks.org.ru

Оффлайн commander

  • Developer
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 1298
  • +0/-0
  • 2
    • Просмотр профиля
    • http://www.webtips.ru
Сравнить два массива
« Ответ #3 : 21 Апреля 2005, 11:32:20 »
Цитировать
этот кусок самый тупой...

какой? вот этот:
my($i,$y);
for($i=0;$i<=scalar @{$files};$i++) {
   for($y=0;$y<=scalar @LIST; $y++) {
      shift @{$files} if($files->[$i] eq $LIST[$y]);
      }
   }
?

если так... то конечно можно переписать его так:
my @arr=("1.txt", "2.exe", "3.dll");
my @files=("1.txt", "2.exe", "5.dll");
map {
 for my $wrong_file(@files)
 {
  shift @arr if($wrong_file eq $_);
 }
}@arr;
print @arr;
но идея от этого не поненяеться... и прирост скорости будет тожк не большой... :)
And no religion too...

Оффлайн cr4ck3r

  • Фанат Perl
  • Постоялец
  • ***
  • Сообщений: 146
  • +0/-0
  • 2
    • Просмотр профиля
    • http://perlmonks.org.ru
Сравнить два массива
« Ответ #4 : 21 Апреля 2005, 11:43:09 »
Да кусок этот.. :(
Ворота в perl - perlmonks.org.ru

Оффлайн AnnA

  • Фанатка форума
  • Старожил
  • ****
  • Сообщений: 263
  • +0/-0
  • 2
    • Просмотр профиля
    • http://
Сравнить два массива
« Ответ #5 : 21 Апреля 2005, 11:47:41 »
cr4ck3r
а почему вы не хотите сравнивать с помощью хэша? Насколько я знаю - верный вариант исключения повторяющихся значений.
пока-пока. :)

Оффлайн commander

  • Developer
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 1298
  • +0/-0
  • 2
    • Просмотр профиля
    • http://www.webtips.ru
Сравнить два массива
« Ответ #6 : 21 Апреля 2005, 11:48:41 »
cr4ck3r
ну возращаемся к основам программирования... есть два массива... как из одного вычесть содержание другого кроме как перебором?
And no religion too...

Оффлайн cr4ck3r

  • Фанат Perl
  • Постоялец
  • ***
  • Сообщений: 146
  • +0/-0
  • 2
    • Просмотр профиля
    • http://perlmonks.org.ru
Сравнить два массива
« Ответ #7 : 21 Апреля 2005, 12:12:31 »
2AnnA: Я пробовал так. Объединял два массива в один и обрабатывал через хэш - то есть как вы говорите исключал повторяющиеся значения - но на выходе я просто получаю уникальные элементы - а мне нужно только те что не содержатся в текстовом файле.
2commander: да... щас попробую вспомнить... (заставлю мозг работать).
Ворота в perl - perlmonks.org.ru

Оффлайн Green Kakadu

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 2757
  • +1/-0
  • 0
    • Просмотр профиля
    • http://gnezdo.webscript.ru
Сравнить два массива
« Ответ #8 : 21 Апреля 2005, 12:56:29 »
Цитировать
cr4ck3r:
Объединял два массива в один и обрабатывал через хэш - то есть как вы говорите исключал повторяющиеся значения

В Perl CookBook есть пример для этого
 в исканиях.

Оффлайн cr4ck3r

  • Фанат Perl
  • Постоялец
  • ***
  • Сообщений: 146
  • +0/-0
  • 2
    • Просмотр профиля
    • http://perlmonks.org.ru
Сравнить два массива
« Ответ #9 : 21 Апреля 2005, 13:05:13 »
................... случайный повтор ........................
Ворота в perl - perlmonks.org.ru

Оффлайн cr4ck3r

  • Фанат Perl
  • Постоялец
  • ***
  • Сообщений: 146
  • +0/-0
  • 2
    • Просмотр профиля
    • http://perlmonks.org.ru
Сравнить два массива
« Ответ #10 : 21 Апреля 2005, 13:06:17 »
Ага. Нашел. Правда в другой книжечке, но все равно спасибо всем. Код такой:

sub Compare {
my $mon=shift;
my $files=shift;# ссылка на массив @FILES
return @{$files} unless(-e "./lib/data/$mon$CONFIG{\'year\'}.txt");# возвращаем полный список - если файла нет
open(LIST,"<","./lib/data/$mon$CONFIG{\'year\'}.txt")|| GetError("Can\'t open data file $mon$CONFIG{\'year\'}: $!");
my @LIST=;
close(LIST);
### вот он! ##########
my %seen=();
foreach (@LIST) {
      chomp;
      $seen{$_}=1;
}
my @clean=grep(! $seen{$_}, @{$files});
#############################
return @clean;      
}
« Последнее редактирование: 21 Апреля 2005, 13:25:26 от cr4ck3r »
Ворота в perl - perlmonks.org.ru

 

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