Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> нужна помощь 
:(
    Опции темы
DooZ
Дата 15.4.2008, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 206
Регистрация: 25.11.2005

Репутация: нет
Всего: 1



косяк в 4 варианте, нельзя использовать запросы более одного слова, иначе не найдет
PM MAIL   Вверх
amg
Дата 15.4.2008, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



DooZ, зачем Вы все время используете конструкцию foreach my $str (<STRS>) ...? Ведь при этом весь файл в виде массива будет помещен в оперативную память. А если ее не хватит? Сами же говорите -- файлы большие. Используйте лучше while (my $str = <STRS>) .... Файл будет обрабатываться построчно, и, может быть, даже быстрее.
PM MAIL   Вверх
sir_nuf_nuf
Дата 15.4.2008, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



странно, у меня 3ий вариант работает нормально

файлы:

first:
Код

mama mila ramu
riki tiki tavi
tavi mama


second:
Код

mama
tavi



tavi:
Код

riki tiki tavi
tavi mama


mama:
Код

mama mila ramu
tavi mama



--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
yura_nev
Дата 15.4.2008, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 28.12.2007

Репутация: нет
Всего: нет



Код

perl -ne 'BEGIN{open$h,"keys.txt";chomp&&open($k{" $_ "},">",$_)for<$h>;close$h;@w=keys%k;}$s=$_;s/\s+/ /;$_=" $_ ";for$w(@w){if(index($_,$w)>=0){$h=$k{$w};print $h $s}}' big_text_file.txt

keys.txt - файл слов, одна строка - одно слово
big_text_file.txt - файл для разбора

Цитата
здесь перебор ключей осуществляется движком regex. Не думаю, что он делает оптимизацию для поиска 
по нескольким ключам, скорее всего просматривает строку на наличие каждго ключа последовательно.
perlre
perldoc -f study
PM MAIL   Вверх
DooZ
Дата 15.4.2008, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 206
Регистрация: 25.11.2005

Репутация: нет
Всего: 1



2amg - foreach не мой вариант, а вариант sir_nuf_nuf
мой пример (исходник) без этих циклов
PM MAIL   Вверх
amg
Дата 15.4.2008, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Цитата(DooZ @  15.4.2008,  13:59 Найти цитируемый пост)
2amg - foreach не мой вариант
Да, действительно, прошу прощения. 

yura_nev, Вы дискредитируете идею перловских однострочников smile 

Кстати, DooZ, мысль yura_nev использовать index для определения наличия слова в строке может быть плодотворной. Эта функция гораздо быстрее, чем регулярные выражения или split.
PM MAIL   Вверх
yura_nev
Дата 15.4.2008, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 28.12.2007

Репутация: нет
Всего: нет



amg, каким образом?
вообще говоря, мне просто лень было открывать редактор
PM MAIL   Вверх
sir_nuf_nuf
Дата 15.4.2008, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



Цитата(amg @ 15.4.2008,  14:26)
Цитата(DooZ @  15.4.2008,  13:59 Найти цитируемый пост)
2amg - foreach не мой вариант
Да, действительно, прошу прощения. 

yura_nev, Вы дискредитируете идею перловских однострочников smile 

Кстати, DooZ, мысль yura_nev использовать index для определения наличия слова в строке может быть плодотворной. Эта функция гораздо быстрее, чем регулярные выражения или split.

это мой вариант..
действительно, чтение в списковом громадных файлов в списковом контексте - не лучшая идея.
как то не подумал =(

идея строить индексы с помощью study  - великолепно =)

я думаю такую задачу лучше решить на С например, написать алгоритм для поиска по нескольким ключам одновременно. По идее требуется всего один проход по строке, чуть быстрее чем при построении индекса.





--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
GoDleSS
Дата 15.4.2008, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 105
Регистрация: 11.2.2007
Где: Пироговский

Репутация: 2
Всего: 2



Если работать индексом, то врят ли получится оптимизировать сильно, так что вот такой набросок:
Код

#!perl

my $dict = 'dict2.txt';
my $dbf = 'db.txt';
my $output = 'output';

parse_long($dbf, $dict, $output);

sub parse_long {
    my ($dbf, $dict_link, $output) = (
        shift || return,
        get_dict(shift) || return,
        shift || '.'
    );

    my (%struct, $keyword);

    open(DBF, $dbf);
        while(<DBF>) {
            next if ($_ eq '');#удалить, если файл точно без пустых строк
            foreach $keyword (@$dict_link) {
                if ( index($_, $keyword)+1 ) {
                    push(@{ $struct{$keyword} }, $_);
                }
            }
        }
    close(DBF);

    foreach (keys %struct) {
        open(OF, ">$output/$_");
            print OF @{ $struct{$_} };
        close(OF);
    }
}

sub get_dict {
    my $file=shift;
    my @dict;
    open(DF, $file);
        while(<DF>) {
            chomp;
            push(@dict, $_);
        }
    close(DF);
    return \@dict;
}



Куча минусов, в том числе и регистрозависимость поиска.
Ну уж если важна скорость )
--------------------
It's a nice day to die my friend!
PM MAIL WWW ICQ   Вверх
sir_nuf_nuf
Дата 15.4.2008, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 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.


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
GoDleSS
Дата 15.4.2008, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 105
Регистрация: 11.2.2007
Где: Пироговский

Репутация: 2
Всего: 2



Цитата

sub get_dict 
{
    open my $file "<<$_[0]" or die "for ever";
    my @strs = <$file>;
    chomp @strs;
    return \@strs;
}

Не красиво оставлять открытыми потоки ввода/вывода ;)

Но 
Код

chomp @strs;

для меня новость, спасибо )

Цитата

говорили про то, что 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"

очень сомневаюсь, что даже такая констукция, при малой длине строки и большом кол-ве этих строк, будет работать заметно быстрее, чем index/rindex.
Хотя... ...практика покажет smile

Цитата

я же имелл в виду другой алгоритм, когда поиск идет по всем ключам сразу, но его лучше писать на C.

Любопытно: 
Поделить на потоки? Либо сложный алгоритм, либо будет неэффективно.
В другом случае все равно все сведется к перебору, думаю понятно почему.

Может я что-то упускаю?
--------------------
It's a nice day to die my friend!
PM MAIL WWW ICQ   Вверх
sir_nuf_nuf
Дата 16.4.2008, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



Цитата

Не красиво оставлять открытыми потоки ввода/вывода ;)

да не красиво =) по этому я и написал эту функцию так.
поверьте (проверьте) в этом случае хендлер закрывается автоматически при выходе из блока.
в этом фишка использования лексических переменных =)
здесь переменная my $file ссылка на объект IO::File
при выходе из блока мы потеряем ссылку на объект, perl вызовет его DESTRUCTOR и поток будет закрыт =)

я представляю себе такой алгоритм: 

из слов - ключей строим дерево начиная с первой буквы.
например для ключей 

Код

ааа
ааb
abc
b


дерево будет выглядеть так:
Код

          root
           /  \
         a     b
        /  \
      a     b
     /  \     \
   a     b    c


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

Если мы пришли в лист дерева то мы нашли ключ в строке, например root -> a -> b -> c соответсвует найденному ключу abc.
Запоминаем, что мы нашли определенный ключ, передвигаем позицию вперед на длину ключа.

В случае если мы не можем спускаться дальше, например нет пути root -> a -> b -> x, то мы увеличиваем позицию на 1 символ.

(заметим, что строку мы проходим всего один раз, правда постоянно заглядывая немного вперед и возвращаясь назад)
в таком случае нам прийдется считать около длинна_строки * на средняя_высота_дерева символов, что как мне кажется оптимально.


Возможно, что оптимизатор регулярных выражений и догадывается делать поиск таким образом для шаблонов вида 
ааа|ааb|abc|b

как видите - не совсем перебор. мы ищем все ключи сразу =)
такой алгоритм не удобно писать на perl - в нем поддержки посимвольной обработки строк ( о не говорите мне про split(//,"..."));

Это сообщение отредактировал(а) sir_nuf_nuf - 16.4.2008, 00:49


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
GoDleSS
Дата 16.4.2008, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 105
Регистрация: 11.2.2007
Где: Пироговский

Репутация: 2
Всего: 2



Цитата

такой алгоритм не удобно писать на perl - в нем поддержки посимвольной обработки строк ( о не говорите мне про split(//,"..."));

Согласен, что неэффективно решать данную проблему на перл. Если уж зашла речь о "ручном" разборе потока, лучше и решать более быстрыми, "классическими" инструментами, как то С.

Однако, используя perl также можно прийти к посимвольному чтению, достаточно пользоваться getc, [sys]read.
Сравнивать на эквивалентность односимвольных строк с помощью eq. В менее шустром варианте, опять же, с помощью index.
Для perl сие извращение, но возможность есть smile

Цитата

Возможно, что оптимизатор регулярных выражений и догадывается делать поиск таким образом для шаблонов вида 
ааа|ааb|abc|b

Сомневаюсь.

--------------------
It's a nice day to die my friend!
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0570 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.