Leser: 1
![]() |
|< 1 2 3 >| | ![]() |
21 Einträge, 3 Seiten |
1
2
3
4
5
6
7
8
9
10
11
12
my(@ids) = qw/1 3 4 12 41 43 44 55 67 78 103 156 167 176 198 244 300 345 355/;
my($id, $idx) = (4, undef);
sub binSearch {
my($arrRef, $val, $minIdx, $maxIdx) = @_;
my($mid) = int(($maxIdx + $minIdx)/ 2);
my($idx);
return(($arrRef->[$mid] == $val) ? $mid : (($minIdx == $maxIdx) ? undef : (($arrRef->[$mid] >= $val) ? binSearch($arrRef, $val, $minIdx, $mid) : binSearch($arrRef, $val, $mid+1, $maxIdx))));
}
printf("IDX: %s\n", defined($idx=binSearch(\@ids, $id, 0, $#ids)) ? $idx : "UNDEF");
$arrRef->[$mid] >= $val
@ids = qw/10 20 30 40 50/;
1
2
3
4
5
6
7
1 return $arrRef->[$mid] == $val
2 ? $mid
3 : $minIdx == $maxIdx
4 ? undef
5 : $arrRef->[$mid] >= $val
6 ? binSearch($arrRef, $val, $minIdx, $mid)
7 : binSearch($arrRef, $val, $mid+1, $maxIdx);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark qw/cmpthese/;
my @ids=(int(rand(10)));
push(@ids,$ids[-1]+int(rand(10))) while(@ids<10000);
my $id=$ids[int(rand(scalar(@ids)))];
cmpthese (-1,
{
'docsnyder' => sub { binSearch(\@ids, $id, 0, $#ids) },
'ToPeG' => sub { tpgSearch(\@ids, $id, 0, $#ids) },
}
);
sub binSearch {
my($arrRef, $val, $minIdx, $maxIdx) = @_;
my($mid) = int(($maxIdx + $minIdx)/ 2);
my($idx);
return(($arrRef->[$mid] == $val) ? $mid : (($minIdx == $maxIdx) ? undef : (($arrRef->[$mid] >= $val) ? binSearch($arrRef, $val, $minIdx, $mid) : binSearch($arrRef, $val, $mid+1, $maxIdx))));
}
sub tpgSearch
{
my ($ref, $val, $min, $max) = @_;
if($id>=$$ref[$min] && $id<=$$ref[$max])
{
my $diff=($ids[$max]-$ids[$min])/($max-$min);
my $pos=int($val/$diff);
if($$ref[$pos]<$val)
{ $pos++ while($val>$$ref[$pos]); }
elsif($$ref[$pos]>$val)
{ $pos-- while($id<$$ref[$pos]); }
return $pos if($val==$$ref[$pos]);
}
return undef;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
sub tpgSearch
{
my ($ref, $val, $min, $max) = @_;
return undef if($max==$min);
return $min if($$ref[$min]==$val);
return $max if($$ref[$max]==$val);
my $diff=($ids[$max]-$ids[$min])/($max-$min);
my $pos=$min+int(($val-$ids[$min])/$diff);
if($$ref[$pos]==$val)
{ return $pos; }
else
{
if($$ref[$pos]<$val)
{
my $n_max=$pos+int(($val-$$ref[$pos])/$diff);
$max=$n_max<@{$ref}?$n_max:@{$ref};
$min=$pos;
if($min==$max)
{
$pos++ while($$ref[$pos]<$val);
return $$ref[$pos]==$val?$pos:undef;
}
}
if($$ref[$pos]>$val)
{
my $n_min=$pos-int(($$ref[$pos]-$val)/$diff);
$min=$n_min>0?$n_min:0;
$max=$pos;
if($min==$max)
{
$pos-- while($$ref[$pos]>$val);
return $$ref[$pos]==$val?$pos:undef;
}
}
return tpgSearch($ref,$val,$min,$max);
}
}
@ids = ( 0..10000, 10000000000);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use strict;
use warnings;
use Data::Dumper;
use Benchmark qw(cmpthese);
my @ids = (0..10000);
my $id = 10000;
Benchmark::cmpthese(-1,{
'docSearch' => sub { docSearch(\@ids, $id, 0, $#ids) },
'tpgSearch' => sub { tpgSearch(\@ids, $id, 0, $#ids) },
'tunSearch' => sub { tunSearch(\@ids, $id, 0, $#ids) },
});
sub tunSearch {
my ($arrRef, $val, $minIdx, $maxIdx) = @_;
my $mid;
while ($minIdx != $maxIdx) {
$mid = int(($maxIdx + $minIdx)/ 2);
if ($arrRef->[$mid] == $val) {
return $mid;
} elsif ($arrRef->[$mid] > $val) {
#? docSearch($arrRef, $val, $minIdx, $mid)
$maxIdx = $mid
} else {
#: docSearch($arrRef, $val, $mid+1, $maxIdx);
$minIdx = $mid+1;
}
}
return undef;
}
sub docSearch {
my ($arrRef, $val, $minIdx, $maxIdx) = @_;
my $mid = int(($maxIdx + $minIdx)/ 2);
return $arrRef->[$mid] == $val
? $mid
: $minIdx == $maxIdx
? undef
: $arrRef->[$mid] > $val
? docSearch($arrRef, $val, $minIdx, $mid)
: docSearch($arrRef, $val, $mid+1, $maxIdx);
}
sub tpgSearch {
my ($ref, $val, $min, $max) = @_;
if($id >= $$ref[$min] && $id <= $$ref[$max]) {
my $diff = ($ref->[$max] - $ref->[$min]) / ($max - $min);
my $pos = int($val / $diff);
if ($$ref[$pos] < $val) {
$pos++ while ($val > $$ref[$pos]);
} elsif($$ref[$pos] > $val) {
$pos-- while ($val < $$ref[$pos]);
}
return $pos if $val == $$ref[$pos];
}
return undef;
}
![]() |
|< 1 2 3 >| | ![]() |
21 Einträge, 3 Seiten |