![]() |
|
Модераторы: ginnie, korob2001 |
![]()
|
|
| burakov |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 554 Регистрация: 28.7.2006 Репутация: нет Всего: нет |
Добрый день
есть массив ссылок на массивы... (двухмерный массив) не хеш (индексы числовые). и вот из этого первого массива нужно удалить те ссылки на массивы, которые встречаются более одного раза. другими словами: найти и удалить дубликаты из двухмерного массива... целый день сижу уже - башка дальше первого уровня не варит пожалуйста дайте код - как это сделать... Спасибо... огромное... навсякий случай код как я создал двумерный массив вот есть файл TXT через 3 строки разделенный символом * вот то что между звездочками это массив второго уровня, а массив первого уровня это массив ссылок на массивы второго уровня
... все ж таки пока писал подумал и .... не дубликаты нужно удалить, а дубликаты массивов на которые ссылаются ссылки массива первого уровня, нужно чтобы в массиве первого уровня остались ссылки на массив уникальных массивов второго уровня вообщем во так Это сообщение отредактировал(а) burakov - 12.8.2009, 16:34 |
|||
|
||||
| ginnie |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 6 Всего: 49 |
burakov, для массивов второго уровня надо придумать хэш-функцию, по которой находить одинаковые массивы. Далее задача легко решается с помощью хэша.
-------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
|||
|
||||
| amg |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1145 Регистрация: 3.8.2006 Где: Новосибирск Репутация: 9 Всего: 50 |
Например, так:
Если строки в файле очень длинные, то сэкономить немного памяти можно, используя в качестве хэширующей функции не объединение в строку элементов массива второго уровня, а, например, md5-сумму этой строки. |
|||
|
||||
| sir_nuf_nuf |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: нет Всего: 31 |
amg, вам, как любителю написать покороче еще вариант
если в массиве не ссылки то можно и
|
||||
|
|||||
| burakov |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 554 Регистрация: 28.7.2006 Репутация: нет Всего: нет |
Огромное спасибо...
попробовал
действительно - это работает.... Но я просто в ступоре понимаю, что я прошу сильно много, но все же если у кого из авторов (или других грамотных товарищей) будет время и силы.... прокомментируйте пожалуйста код.... так все компактно написано... что начинающему трудно понять Понял только, что grep чего то фильтрует из массива @array но вот это вот {! $h{"@$_"}++} ??? |
|||
|
||||
| sir_nuf_nuf |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: нет Всего: 31 |
grep для каждого элемента массива выполняет код
Если результат окажется истинным - то элемент проходит, нет - отбрасывается. Что делает это код: "@$_" - это склеивает элемент массива (который является ссылкой на другой массив) в строку Так если $a = [3,4,5,6,1]; то "@$a" = "34561" - строка. Далее это строка используется как ключ в хеше %h. Если она туда уже помещалась (т.е. мы наткнулись на дубль), то $h{"@$_"} - вернет истину, !$h{"@$_"} - вернет ложь и это элемент будет отброшен как не уникальный. В случае, если такого ключа в хэше еще нет (т.е. это уникальный элемент) - то ключ добавляется в хеш с помощью автоинкримента $h{"@$_"}++ На самом деле автоинкримент проистходит всегда, просто для элементов которые кладутся в хеш впервые $h{"@$_"}++ - ложь а для тех что не впревые истина. В оригинале эта фича выглядела так:
Это amg ее приспособил под начальные условия. Добавлено через 1 минуту и 14 секунд Ну кстати .. для вашей задачи можно приспособить и мой вариант:
|
||||||||
|
|||||||||
| burakov |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 554 Регистрация: 28.7.2006 Репутация: нет Всего: нет |
Спасибо,
sir_nuf_nuf но Ваш вариант мне еще более непонятен (хотя в принципе не "более" , а "также") просто я в своих книжках функцию map не нашел... если не трудно пожалуйста прокомментируйте пожалуйста и свой код
Спасибо. я так понял изначально все эти дела применяются для удаления дубликатов из обыкновенного одномерного массива... чем и занялся чтобы понять как все работает... и возникли вопросы
$h{"$_"}++ почему то работает и без восклицательного знака (и с восклицательным знаком тоже работает)... а вот без ++ не работает хотя вроде бы должно... (судя по приведенному выше разъяснению) так что хотя все работает Это сообщение отредактировал(а) burakov - 13.8.2009, 09:29 |
||||
|
|||||
| sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: нет Всего: 31 |
выкидывай их. или на розжиг костра. perldoc map Попробуй запустить это:
Стало понятнее ? не работает. Вам показалось. В таком случае вы отбрасывает первый встретившийся элемент, а кладете все ему равные - как результат действительно уникальные элементы в результат не попадают. |
|||
|
||||
| ginnie |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 6 Всего: 49 |
burakov, имейте ввиду, что хэш-функцию нужно выбирать исходя из данных очень аккуратно. Например, если использовать в качестве хэш-функции конкатенацию элементов через пробел ("@$_"), то массивы (1,2,3) и ('1 2', 3) будут неверно интерпретированы, как одинаковые.
-------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
|||
|
||||
| KSURi |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 5 Всего: 27 |
Кстати, простая конкатенация не будет является хэш-функцией массива)
Чтобы избежать ситуации, которую описал ginnie, достаточно воспользоваться встроенной функцией crypt(). -------------------- Died at Life.pl line 21 |
|||
|
||||
| ginnie |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 6 Всего: 49 |
KSURi, ты абсолютно прав, только не написал, почему "простая конкатенация не будет является хэш-функцией" (из-за того, что результат хэш-функции должен иметь фиксированную длину, я уже про это забыл
-------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
|||
|
||||
| burakov |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 554 Регистрация: 28.7.2006 Репутация: нет Всего: нет |
Спасибо...
Кое что я понял, хотя до полного понимания вопроса ее чувствую далеко... поскольку удаление дубликатов из массива довольно распространенная необходимость... Прошу опытных товарищей привести пример кода удаления дубликатов из двумерного массива с использованием функции crypt() (чтобы исключить вариант описанный ginnie). Спасибо. |
|||
|
||||
| KSURi |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 5 Всего: 27 |
Вы попробуйте сами сначала написать, а потом вам помогут ошибки поправить
-------------------- Died at Life.pl line 21 |
|||
|
||||
| shamber |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1422 Регистрация: 5.9.2006 Где: Россия Репутация: 1 Всего: 18 |
KSURi, да ладно
|
|||
|
||||
| ginnie |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 6 Всего: 49 |
burakov, я тут немного подумал, и понял, что не совсем корректно описал свое решение в самом начале.
для массивов второго уровня нам надо выбрать не хэш-функцию, а функцию, представляющую все элементы массива в виде одного, который будет подаваться на вход хэш-функции при создании элемента хэша. Если известно, что в данных точно не будет какого-либо символа, то можно этот символ использовать в конкатенации элементов массива. Если я правильно понял, KSURi, предлагает использовать
Такой вариант не исключает возможности получения одинакового представления для двух разных массивов, но это крайне маловероятно. -------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
||||
|
|||||
![]()
|
| Правила форума "Perl: Системное программирование" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Perl: Системное программирование | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |