![]() |
|
Модераторы: korob2001, ginnie |
![]()
|
|
| DooZ |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 206 Регистрация: 25.11.2005 Репутация: нет Всего: 1 |
косяк в 4 варианте, нельзя использовать запросы более одного слова, иначе не найдет
|
|||
|
||||
| amg |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1145 Регистрация: 3.8.2006 Где: Новосибирск Репутация: 38 Всего: 50 |
DooZ, зачем Вы все время используете конструкцию foreach my $str (<STRS>) ...? Ведь при этом весь файл в виде массива будет помещен в оперативную память. А если ее не хватит? Сами же говорите -- файлы большие. Используйте лучше while (my $str = <STRS>) .... Файл будет обрабатываться построчно, и, может быть, даже быстрее.
|
|||
|
||||
| sir_nuf_nuf |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 14 Всего: 31 |
странно, у меня 3ий вариант работает нормально
файлы: first:
second:
tavi:
mama:
|
||||||||
|
|||||||||
| yura_nev |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 28.12.2007 Репутация: нет Всего: нет |
keys.txt - файл слов, одна строка - одно слово big_text_file.txt - файл для разбора
perldoc -f study |
||||
|
|||||
| DooZ |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 206 Регистрация: 25.11.2005 Репутация: нет Всего: 1 |
2amg - foreach не мой вариант, а вариант sir_nuf_nuf
мой пример (исходник) без этих циклов |
|||
|
||||
| amg |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1145 Регистрация: 3.8.2006 Где: Новосибирск Репутация: 38 Всего: 50 |
Да, действительно, прошу прощения.
yura_nev, Вы дискредитируете идею перловских однострочников Кстати, DooZ, мысль yura_nev использовать index для определения наличия слова в строке может быть плодотворной. Эта функция гораздо быстрее, чем регулярные выражения или split. |
|||
|
||||
| yura_nev |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 28.12.2007 Репутация: нет Всего: нет |
amg, каким образом?
вообще говоря, мне просто лень было открывать редактор |
|||
|
||||
| sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 14 Всего: 31 |
это мой вариант.. действительно, чтение в списковом громадных файлов в списковом контексте - не лучшая идея. как то не подумал =( идея строить индексы с помощью study - великолепно =) я думаю такую задачу лучше решить на С например, написать алгоритм для поиска по нескольким ключам одновременно. По идее требуется всего один проход по строке, чуть быстрее чем при построении индекса. |
|||
|
||||
| GoDleSS |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 105 Регистрация: 11.2.2007 Где: Пироговский Репутация: 2 Всего: 2 |
Если работать индексом, то врят ли получится оптимизировать сильно, так что вот такой набросок:
Куча минусов, в том числе и регистрозависимость поиска. Ну уж если важна скорость ) --------------------
It's a nice day to die my friend! |
|||
|
||||
| sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 14 Всего: 31 |
функция get_dict пишется проще
sub get_dict { open my $file "<<$_[0]" or die "for ever"; my @strs = <$file>; chomp @strs; return \@strs; } и вы не поняли про индекс. имелась ввиду не функция index. говорили про то, что study $str создает скрытую структуру данных для строки $str при чем поиск для такой строки будет происходить намного быстрее. примерно так: $str = "mama mila lamu" будет создан индекс букв: a - 1,3,8,11 m - 0,2,5,12 i - 6 l - 7,10 u - 13 теперь когда мы будем искать подстроку "mu" мы не будем просматривать строку с самого начала, мы по индексу найдем , что "u" встречается в 13 позиции, а потом проверим, что в 12 позиции есть буква "m" вот примерно так работает study + regex perldoc -f study =) я же имелл в виду другой алгоритм, когда поиск идет по всем ключам сразу, но его лучше писать на C. |
|||
|
||||
| GoDleSS |
|
||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 105 Регистрация: 11.2.2007 Где: Пироговский Репутация: 2 Всего: 2 |
Не красиво оставлять открытыми потоки ввода/вывода ;) Но
для меня новость, спасибо )
очень сомневаюсь, что даже такая констукция, при малой длине строки и большом кол-ве этих строк, будет работать заметно быстрее, чем index/rindex. Хотя... ...практика покажет
Любопытно: Поделить на потоки? Либо сложный алгоритм, либо будет неэффективно. В другом случае все равно все сведется к перебору, думаю понятно почему. Может я что-то упускаю? --------------------
It's a nice day to die my friend! |
||||||||
|
|||||||||
| sir_nuf_nuf |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 14 Всего: 31 |
да не красиво =) по этому я и написал эту функцию так. поверьте (проверьте) в этом случае хендлер закрывается автоматически при выходе из блока. в этом фишка использования лексических переменных =) здесь переменная my $file ссылка на объект IO::File при выходе из блока мы потеряем ссылку на объект, perl вызовет его DESTRUCTOR и поток будет закрыт =) я представляю себе такой алгоритм: из слов - ключей строим дерево начиная с первой буквы. например для ключей
дерево будет выглядеть так:
далее отмечаем позицию в строке (в которой ищем), выбираем последовательно буквы из строки начиная с этой позиции. Для каждой выбранной буквы спускаем вниз по дереву ключей. Если мы пришли в лист дерева то мы нашли ключ в строке, например root -> a -> b -> c соответсвует найденному ключу abc. Запоминаем, что мы нашли определенный ключ, передвигаем позицию вперед на длину ключа. В случае если мы не можем спускаться дальше, например нет пути root -> a -> b -> x, то мы увеличиваем позицию на 1 символ. (заметим, что строку мы проходим всего один раз, правда постоянно заглядывая немного вперед и возвращаясь назад) в таком случае нам прийдется считать около длинна_строки * на средняя_высота_дерева символов, что как мне кажется оптимально. Возможно, что оптимизатор регулярных выражений и догадывается делать поиск таким образом для шаблонов вида ааа|ааb|abc|b как видите - не совсем перебор. мы ищем все ключи сразу =) такой алгоритм не удобно писать на perl - в нем поддержки посимвольной обработки строк ( о не говорите мне про split(//,"...")); Это сообщение отредактировал(а) sir_nuf_nuf - 16.4.2008, 00:49 |
||||||
|
|||||||
| GoDleSS |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 105 Регистрация: 11.2.2007 Где: Пироговский Репутация: 2 Всего: 2 |
Согласен, что неэффективно решать данную проблему на перл. Если уж зашла речь о "ручном" разборе потока, лучше и решать более быстрыми, "классическими" инструментами, как то С. Однако, используя perl также можно прийти к посимвольному чтению, достаточно пользоваться getc, [sys]read. Сравнивать на эквивалентность односимвольных строк с помощью eq. В менее шустром варианте, опять же, с помощью index. Для perl сие извращение, но возможность есть
Сомневаюсь. --------------------
It's a nice day to die my friend! |
||||
|
|||||
![]()
|
| Правила форума "Perl" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Perl: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |