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

Поиск:

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


Эксперт
***


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

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



Господа!
Нужно эффективное решение.
Требуется заменить каждую из непрерывной последовательности букв "N" на "M". Последовательность, подлежащая замене, ограничена слева буквой "X" и справа "Y". 
Один вариант у меня есть, но не уверен, что он (самый) хороший.
Код

$str = 'XNNYaaaANNBaaXNNNNY';
$str =~ s/(?<=X)(N+)(?=Y)/'M' x length($1)/eg;
print "$str\n";

У кого есть другие варианты, предлагайте, пожалуйста.
Должно получиться 
Код

XMMYaaaANNBaaXMMMMY

PM MAIL   Вверх
Nab
Дата 23.12.2006, 23:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



У меня есть вот такой вариант:
Код

while ($str =~ s/(XM*)N(N*Y)/$1M$2/go) {};



--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
nitr
Дата 24.12.2006, 06:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



банально smile (без "заглядываний")
Код

$str =~ s/X(N+)Y/'X'.('M' x length($1)).'Y'/eg;

по-детски (но весело):
Код

for (my $i = 0;$i< length($str);$i++) {
    $sym = substr($str, $i, 1);
    $e = 1 if $sym eq 'X';
    $e = 0 if $sym eq 'Y';
    substr($str, $i, 1) = 'M' if $sym eq 'N' and $e == 1;
}




--------------------
PM   Вверх
amg
Дата 25.12.2006, 09:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Nab, nitr, спасибо!
Привожу результаты тестирования кода на скорость (Benchmark, 2e6 циклов на строке длиной 20 символов) и память (Memchmark, на строке длиной 20e6 символов)
Код

        Bencmark Memchmark
   me:   1.29 s    37 Mb
  Nab:   2.32 s    53 Mb
nitr1:   0.78 s    38 Mb
nitr2:  46.96 s     0 Mb

PM MAIL   Вверх
nitr
Дата 25.12.2006, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



amg, тест повтори, но поменяй местами мой и твой скрипт smile


--------------------
PM   Вверх
amg
Дата 25.12.2006, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Повторил, поменяв местами "me" и "nitr1". Результат тот же (по памяти поменялись местами, но это нормально, в документации к Memchmark предупреждают, что точность не гарантируется). 

nitr, что-то показалось неожиданным?
PM MAIL   Вверх
Nab
Дата 25.12.2006, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Вот блин, оказался самым тормознутым, и самым толстым... smile

amg, а проверь плиз вот такой вариант:
Код

$str =~ s/(?<=X)(N+)(?=Y)/($_=$1)=~tr{N}{M};$_/ge;


Добавлено @ 13:54 
Кстати, мой первый вариант не корректен, потому как поймает и просто 'XMNNY' smile
Я думаю что вариант nitra, свмый оптимальный...
там очень простой паттерн и минимум вычислений...

Сложные регекспы растут во времени экспоненциально smile

Можно и мой по такому принципу попробовать:
Код

$str =~ s/X(N+)Y/($_=$1)=~tr{N}{M};'X'.$_.'Y'/ge;



--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
amg
Дата 29.12.2006, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Nab @  25.12.2006,  13:41 Найти цитируемый пост)
Можно и мой по такому принципу попробовать:
Почти так же быстро, как и вариант nitr'а.

Основной вывод: при замене в регулярных выражения заглядывание вперед/назад занимает больше времени, чем повторение выражения и конкатенация в правой части регулярки.

Еще раз спасибо всем! С Новым годом!

PM MAIL   Вверх
tishaishii
Дата 30.12.2006, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Создатель
***


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

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



Код
($\, $,)=("\n", "\t");
my@del=qw(X Y);
my@let=qw(N M);
my($rx, $lenX, $len, %was)=(qr(\Q$del[0]\E(\Q$let[0]\E+)\Q$del[1]\E)s, length $del[0]);
my$str='XNNYaaaANNBaaXNNNNY';
study $str;
substr($str, $lenX+length $`, $len)=$was{+($len=length $1)}||=$let[1] x $len while $str=~m{$rx}gc;
print $str;

Попробуй попользоваться ещё http://search.cpan.org/author/MJD/Memoize-1.01/Memoize.pm.

Это сообщение отредактировал(а) tishaishii - 30.12.2006, 15:29
PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


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

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


 




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


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

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