Mr. Shawn H. Corey wrote:
> Your solution will only work if $element is unique. Otherwise you will
> have multiple copies of $element on the list, and not the $maximum
> (unique) number of items.
>
> Try:
>
> @recent = grep { ! /^$element$/ } @recent;
> unshift @recent, $element;
> $#recent = $maximum;
>
> Notice how things became even slower?
>
>
OK, here's a solution that might be faster. The problem with it is
as_array() which has to scan the list every time. There is not simpler
way for it to work.
#!/usr/bin/perl
use strict;
use warnings;
my $maximum = 20; # minimum maximum == 2
my $head = 0;
my $tail = 0;
my %unique = ();
my $count = 0;
sub add_element {
my $element = shift @_;
my $node = {
next => 0,
back => 0,
data => $element,
};
if( exists $unique{$element} ){
if( $unique{$element} eq $head ){
$head = $unique{$element}->{next};
}else{
$unique{$element}->{back}->{next} = $unique{$element}->{next};
}
if( $unique{$element} eq $tail ){
$tail = $unique{$element}->{back};
}else{
$unique{$element}->{next}->{back} = $unique{$element}->{back};
}
}
if( ref( $head )){
$node->{next} = $head;
$head->{back} = $node;
}else{
$tail = $node;
}
$head = $node;
$unique{$element} = $node;
$count ++;
if( $count > $maximum ){
my $item = $tail->{data};
$tail = $tail->{back};
$tail->{next} = 0;
delete $unique{$item};
}
}
sub as_array {
my @array = ();
my $node = $head;
while( ref( $node )){
push @array, $node->{data};
$node = $node->{next};
}
return @array;
}
for my $n ( qw( a b c b a a b c d e f g h i j k l m n o p q r s t u v w
x y z ) ){
add_element( $n );
print join( " ", as_array ), "\n";
}
--
__END__
Just my 0.00000002 million dollars worth,
--- Shawn
"For the things we have to learn before we can do them, we learn by
doing them."
Aristotle
* Perl tutorials at http://perlmonks.org/?node=Tutorials
* A searchable perldoc is at http://perldoc.perl.org/
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>