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>


Reply via email to