ocehb: (Default)
[personal profile] ocehb
как со строкой: s#^\s+##; s#\s+$##; s#\s+# #g;



DB<2> p join",",map { defined($_)?$_:"undef" } @a
undef,undef,1,2,3,undef,undef,undef,4,undef,5,undef,undef,6,undef,undef
DB<3> my ($a,$b) = (0,0); map { defined($_) ? ($a++,$b=0) : ($b++&&splice@a,$a++,1) } @a
DB<4> defined($a[0])||splice@a,0,1
DB<5> defined($a[$#a])||splice@a,$#a,1
DB<6> p join",",map { defined($_)?$_:"undef" } @a
1,2,3,undef,4,undef,5,undef,6


upd:


map { defined($_) ? ($a++,$b=0) : ($b++?splice@_,$a,1:$a++); } @_;

Date: 2007-03-25 11:24 pm (UTC)
From: [identity profile] gone-one.livejournal.com
Забавный вариант без использования "лишних" переменных:
sub clean_array{push@_,undef;defined$_[0]||defined$_[-1]?push@_,shift:shift for 1..@_;pop;@_}

Date: 2007-03-25 11:39 pm (UTC)
From: [identity profile] gone-one.livejournal.com
О, вдогонку - оно же "в стихах" :))) http://gone-one.livejournal.com/90093.html

Date: 2007-07-13 07:36 pm (UTC)
From: [identity profile] deepone.livejournal.com
А давайте я к вам тоже со своей версией и мотивацией:
#!/usr/bin/perl

use Benchmark qw(:all);

my @a=((10)x10,(undef)x10)x10;

cmpthese(32768, {
		clean_array1 => sub {clean_array1(@a)},
		clean_array2 => sub {clean_array2(@a)},
		clean_array3 => sub {clean_array3(@a)},
	       });

sub clean_array1{push@_,undef;defined$_[0]||defined$_[-1]?push@_,shift:shift for 1..@_;pop;@_}

sub clean_array2 {
    my ($a,$b) = (0,0); map { defined($_) ? ($a++,$b=0) : ($b++?splice@_,$a,1:$a++); } @_;
}

sub clean_array3 {
    my $buff; grep { $buff ? ($buff=$_)||1 : ($buff=$_) } @_;
}



Кста, вторая делает что то чтранное вместо чистки.

Date: 2007-07-13 07:49 pm (UTC)
From: [identity profile] deepone.livejournal.com
Ну, спокойной ночи.

Date: 2007-07-15 10:17 am (UTC)
From: [identity profile] gone-one.livejournal.com
Второй вариант действительно фигню какую-то делает, поэтому его не будем рассматривать. К счастью, при программировании на perl прямое и простое решение обычно работает быстрее, чем извращения. Разумеется, мой код с циклическим буфером - это просто интересный пример, ни в коем случае не для использования в production.

Однако, Ваш код при всей его быстроте задачу не решает :)

Во-первых, он не уважает нули. Вот такое он вычистит, в то время как по "условиям задачи" не надо бы:

my @a=((10)x10,(0)x10)x10;

Во вторых, он не отрезает последний undef элемент в массиве (это видно даже по Вашим тестам).


А если это исправить, например так:
sub clean_array4 {
    my $buff; $_ = [grep { defined($buff) ? ($buff=$_)||1 : defined($buff=$_) } @_, undef]; pop @$_; @$_;
}

- то работать это начинает уже не так фантастически быстро. Но, разумеется, быстрее первого варианта.

Date: 2007-07-15 04:54 pm (UTC)
From: [identity profile] deepone.livejournal.com
Бррр.
ну почистить начало и конец - это несложно.
про хвосты я просчто не думаю.
А вот [] - это как раз и есть путь к тормозам.
Вся фишка в том, что хэш и спифок - это базовые типы, и при их присваивании происходит копирование.
копирование - это опирация O(n) - и нам очень жадно, особенно при больших n.
Операция [@a] приводится к my @b=@a; return \@b;
Дописывание андефа в начало и конец - тоже операция над массивом, которая потом разворачивается в кол-во начальных+завершающих андефов.

лучше обрезать потом так:
pop || push; shift || unshift;
или соостветственно
defined($_=pop) || push; defined($_=shift) || unshift;

Date: 2007-07-17 06:23 pm (UTC)
From: [identity profile] gone-one.livejournal.com
Как раз [] позволяют избежать лишнего копирования. Сравните:
sub clean_array5 {
    my $buff; $_ = [grep { defined($buff) ? ($buff=$_)||1 : defined($buff=$_) } @_]; defined($buff = pop @$_) and push @$_, $buff; @$_;
}

sub clean_array6 {
    my $buff; @_ = grep { defined($buff) ? ($buff=$_)||1 : defined($buff=$_) } @_; defined($_ = pop @_) and push @_, $_; @_;
}


Вариант с [] работает на 33% быстрее.


А обрезание типа defined($_=pop) && push действительно выигрывает 1% скорости, если на конце есть undef, и работает примерно так же, если undef нет.

Profile

ocehb: (Default)
ocehb

January 2021

S M T W T F S
     12
345 6789
10111213141516
17181920212223
24252627282930
31      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Feb. 5th, 2026 09:46 pm
Powered by Dreamwidth Studios