음수에는 맞지 않지만 빠릅니다. 당신이 XOR은 음수에 작업 할 경우
사실, 당신은 단지 그들을 캐릭터 라인 화해야합니다
my @array = (-10..-7,-5..10,-10..10);
my $unique;
$unique ^= "$_" for @array;
say $unique;
출력
-6
그리고 일을 몇 가지 빠른 벤치 마크 :
Benchmark: timing 100 iterations of schwern, there_can_be_only_one, tobyink, xor_string...
schwern: 323 wallclock secs (312.42 usr + 7.08 sys = 319.51 CPU) @ 0.31/s (n=100)
there_can_be_only_one: 114 wallclock secs (113.49 usr + 0.02 sys = 113.51 CPU) @ 0.88/s (n=100)
tobyink: 177 wallclock secs (176.76 usr + 0.14 sys = 176.90 CPU) @ 0.57/s (n=100)
xor_string: 98 wallclock secs (97.05 usr + 0.00 sys = 97.05 CPU) @ 1.03/s (n=100)
수학적 번역을 xor-ing하는 것보다 문자열을 xoring하는 것이 15 % 빠릅니다. 양수
결과 - 정렬 된 목록은 어떻게됩니까?
Schwern의 솔루션은 흥미로운 결과를 가져옵니다. 그는 목록을 정렬 한 다음 모든 고유 요소를 검색했습니다.
우리가 doubletons의 군중 만 1 싱글이 있다는 추가 정보를 사용하는 경우, 우리는 신속하게 단순화 할 수 그러나 우리의 비교 4.
의 요인을 감소 페어의 비교를 수행하여 검색 우리 이진 검색을 수행하면 더 잘 수행 할 수 있습니다. 알려진 일치 쌍 사이의 장벽에서 목록을 분리하면 남은 두 목록 중 홀수 인 목록 중 어느 것이 우리 싱글 톤을 포함합니다.나는이 솔루션의 일부 벤치마킹을했고, 더 빨리 (물론) 무엇보다도 크기의 주문이다 :
use strict;
use warnings;
use Benchmark qw(timethese);
sub binary_search {
my $nums = $_[0];
my $min = 0;
my $max = $#$nums;
while ($min < $max) {
my $half = ($max - $min)/2; # should always be an integer
my ($prev, $this, $next) = ($min+$half-1) .. ($min+$half+1);
if ($nums->[$prev] == $nums->[$this]) {
if ($half % 2) { # 0 0 1 1 2 2 3 (half = 3)
$min = $next;
} else { # 0 1 1 2 2 (half = 2)
$max = $prev - 1;
}
} elsif ($nums->[$this] == $nums->[$next]) {
if ($half % 2) { # 0 1 1 2 2 3 3 (half = 3)
$max = $prev;
} else { # 0 0 1 1 2 (half = 2)
$min = $next + 1;
}
} else {
$max = $min = $this;
}
}
return $nums->[$min];
}
sub xor_string {
my $tmp;
$tmp ^= "$_" for @{$_[0]};
}
sub brute {
my $nums = $_[0];
return $nums->[0] if $nums->[0] != $nums->[1];
for (1..$#$nums-1) {
my($prev, $this, $next) = @$nums[$_-1, $_, $_+1];
return $this if $prev != $this && $next != $this;
}
return $nums->[-1] if $nums->[-1] != $nums->[-2];
}
sub pairwise_search {
my $nums = $_[0];
for (my $i = 0; $i <= $#$nums; $i += 2) {
if ($nums->[$i] != $nums->[$i+1]) {
return $nums->[$i];
}
}
}
# Note: this test data is very specific and is intended to take near the maximum
# number of steps for a binary search while shortcutting halfway for brute force
# and pairwise
my @input = sort {$a <=> $b} (0..500_003, 500_005..1_000_000, 0..1_000_000);
#my @input = sort {$a <=> $b} (0..499_996, 499_998..1_000_000, 0..1_000_000);
timethese(1000, {
brute => sub { brute(\@input) },
pairwise => sub { pairwise_search(\@input) },
xor_string => sub { xor_string(\@input) },
binary => sub { binary_search(\@input) },
});
결과 :
Benchmark: timing 1000 iterations of binary, brute, pairwise, xor_string...
binary: 0 wallclock secs (0.02 usr + 0.00 sys = 0.02 CPU) @ 62500.00/s (n=1000)
(warning: too few iterations for a reliable count)
brute: 472 wallclock secs (469.92 usr + 0.05 sys = 469.97 CPU) @ 2.13/s (n=1000)
pairwise: 216 wallclock secs (214.74 usr + 0.00 sys = 214.74 CPU) @ 4.66/s (n=1000)
xor_string: 223 wallclock secs (221.74 usr + 0.06 sys = 221.80 CPU) @ 4.51/s (n=1000)
감사합니다 리 듀헴 편집합니다. – xtreak
목록이 단조롭게 증가한다는 것을 보장합니까? – SzG
@SzG 아니요, 목록은 정렬되지 않으며 음수와 양수를 모두 포함 할 수 있습니다. – xtreak