스탈린 정렬 in perl

내용



지금 최고로 hot으로 rock로 lock인 O(n)로 소트를 할 수 있어요! 그리고 화제의 스탈린 정렬을 perl로 작성했습니다.

스탈린 정렬이란?



htps : // 이 m/타츠키-이/있어 ms/380d6bd06515b872b2b2
(아마) 처음 소개한 분들에게 전부 실려

github:
htps : // 기주 b. 코 m / gus 타 ゔ ぉ에서 빠 ぁ / s 타 ぃ - 소 rt

perl 없는 장! PR 보낼 수 있어!

구현해보기



5초(대 거짓말)로 쓴 코드

splice_stalin_sort.pl
sub splice_stalin_sort {
    my @arr = @_;
    for (my $i = 1; $i <= $#arr; $i++) {
        if ($arr[$i] < $arr[$i-1]) {
            splice(@arr, $i, 1);
            $i--;
        }
    }
    return @arr;
}

이 코드에는 문제가 있습니다! ! ! ! ! 했다
맞습니다 splice htps : // ぺrl c. 페르. rg / 훙 c 치온 s / sp ぃ세. HTML

대체로의 언어로 공통되어 있다고 생각합니다만(모른다)
연결 목록이 아닌 목록에 대한 splice1. 해당 요소 삭제
2. 삭제한 element의 다음 요소를 붙이기

라는 조작이 달립니다. 압도적으로 2번이 늦을 것 같네요! 예, splice는 O(n)입니다.
※주: 연결 리스트의 경우의 요소 삭제는 O(1), 링크 바꾸는 것 뿐. 다만 연결 리스트는 중간 요소에의 액세스가 O(n) 때문에, 이번은 사용하지 않는다

그래서 처음에 붙인 코드의 계산량은 아마 O(n^2) 라고 하는 것이 생각됩니다! 무슨 일이야?

스털링 정렬의 특성상 루프 내에서 수행하는 조작은 반드시 O(1)인 것이 요구되기 때문에,
perl의 Array에서 실행 가능한 조작은 다음과 같습니다.
- 添字アクセス
- delete (※undefになるだけ)
- 最後に追加
- 先頭に追加
- スワップ

그래서 뇌사 수정 한 코드가 여기

push_stalin_sort.pl
sub push_stalin_sort {
    my @arr = @_;
    my @sorted;
    my $max = 0;
    for (my $i = 0; $i <= $#arr; $i++) {
        if ($arr[$i] >= $max) {
            push(@sorted, $arr[$i]);
            $max = $arr[$i];
        }
    }
    return @sorted;
}

이제 1000 개의 배열 길이를 가진 데이터에 대해 각각 1000 번 실행하여 속도를 측정하면
>>> perl perl/stalin-sort.pl
splice_stalin_sort : 0.202442
push_stalin_sort : 0.111881

무려! ! ! ! 놀라움의 2배속! ! ! ! ! ! 굉장해! ! ! ! ! ! !

단지 조금 외형이 아름답지 않네요.
우리는 힘이 있습니다. 그래, 앞서 언급했듯이 delete도 O(1)입니다.
그리고 grep은 O(n)인 것으로 알려져 있습니다. 라는 것은

grep_stalin_sort.pl
sub grep_stalin_sort {
    my @arr = @_;
    my $max = $arr[0];
    for (my $i = 1; $i <= $#arr; $i++) {
        if ($arr[$i] < $max) {
            delete $arr[$i]
        } else {
            $max = $arr[$i];
        }
    }
   return grep defined $_, @arr;
}

이런 코드도 쓸 수 있다! ! ! !
>>> perl perl/stalin-sort.pl                                                                                                                             +[add_perl]
splice stalin_sort : 0.208253
push stalin_sort : 0.110466
delete stalin_sort : 0.118796

(주문 기법과는 다릅니다만) 엄밀히 말하면 2*O(n) 가 되어 있기 때문에
다소 계산 시간은 증가하고 있습니다만, delete해 grep에서도 속도를 유지할 수 있습니다

그래! ! ! ! 이것이! ! ! ! ! ! !
아르고! ! ! ! ! 리즈--↑↑↑↑무! ! ! ! ! ! ! ! ! ! 입니다! ! ! ! ! ! ! ! ! ! 1

卍おわり卍

테스트 코드를 포함한 모든



stalin_sort.pl
use strict;
use warnings;

use Time::HiRes qw(usleep ualarm gettimeofday tv_interval);

sub splice_stalin_sort {
    my @arr = @_;
    for (my $i = 1; $i <= $#arr; $i++) {
        if ($arr[$i] < $arr[$i-1]) {
            splice(@arr, $i, 1);
            $i--;
        }
    }
    return @arr;
}

sub push_stalin_sort {
    my @arr = @_;
    my @sorted;
    my $max = 0;
    for (my $i = 0; $i <= $#arr; $i++) {
        if ($arr[$i] >= $max) {
            push(@sorted, $arr[$i]);
            $max = $arr[$i];
        }
    }
    return @sorted;
}

sub grep_stalin_sort {
    my @arr = @_;
    my $max = $arr[0];
    for (my $i = 1; $i <= $#arr; $i++) {
        if ($arr[$i] < $max) {
            delete $arr[$i]
        } else {
            $max = $arr[$i];
        }
    }
    return grep defined $_, @arr;
}

my @arr1;
my $size  = 1000;
for (my $i = 0; $i < $size; $i++)
{
    my $n = int(rand $size);
    push @arr1, $n;
}

my $times = 1000;
{
    print "splice_stalin_sort : ";
    my $t0 = [gettimeofday];
    for (my $count = 0; $count < $times; $count++)
    {
        splice_stalin_sort(@arr1);
    }
    my $t1 = [gettimeofday];
    my $process_time = tv_interval($t0, $t1);
    print "$process_time\n";
}

{
    print "push_stalin_sort : ";
    my $t0 = [gettimeofday];
    for (my $count = 0; $count < $times; $count++)
    {
        push_stalin_sort(@arr1);
    }
    my $t1 = [gettimeofday];
    my $process_time = tv_interval($t0, $t1);
    print "$process_time\n";

}

{
    print "delete_stalin_sort : ";
    my $t0 = [gettimeofday];
    for (my $count = 0; $count < $times; $count++)
    {
        grep_stalin_sort(@arr1);
    }
    my $t1 = [gettimeofday];
    my $process_time = tv_interval($t0, $t1);
    print "$process_time\n";
}

1;

참고



htps //w w. 페르몬 ks. rg/? 그래서 _이 d = 17890
htps // 55. 하테나 bぉg. 코m/엔트리/2014/09/13/171128
htps : // 기효. jp /에서 v / 세리아 l / 01 / 페르 - c rs - b / 005503

추가





perl 프로의 여러분은 감사합니다.

좋은 웹페이지 즐겨찾기