0

I have various subroutines that give me arrays of arrays. I have tested them separately and somehow when i write my main routine, I fail to make the program recognize my arrays. I know it's a problem of dereferencing, or at least i suspect it heavily.

The code is a bit long but I'll try to explain it:

my @leaderboard=@arrarraa; #an array of arrays
my $parentmass=$spect[$#spect]; #scalar

while (scalar @leaderboard>0) {
        for my $i(0..(scalar @leaderboard-1)) {
        my $curref=$leaderboard[$i]; #the program says here that there is an uninitialized value. But I start with a list of 18 elements.
        my @currentarray=@$curref; #then i try to dereference the array
        my $w=sumaarray (@currentarray);
        if ($w==$parentmass) {
            if (defined $Leader[0]) {
                my $sc1=score (@currentarray);
                my $sc2=score (@Leader);
                if ($sc1>$sc2) {
                    @Leader=@currentarray;
                }

            }
            else {@Leader=@currentarray;}
        }
        elsif ($w>$parentmass) {splice @leaderboard,$i,1;} #here i delete the element if it doesn't work. I hope it's done correctly.

    }
    my $leadref= cut (@leaderboard); #here i take the first 10 scores of the AoAs
    @leaderboard = @$leadref;
    my $leaderef=expand (@leaderboard); #then i expand the AoAs by one term
    @leaderboard= @$leaderef;            #and i should end with a completely different list to work with in the while loop
}   

So I don't know how to dereference the AoAs correctly. The output of the program says:

"Use of uninitialized value $curref in concatenation (.) or string at C:\Algorithms\22cyclic\cyclospectrumsub.pl line 183. Can't use an undefined value as an ARRAY reference at C:\Algorithms\22cyclic\cyclospectrumsub.pl line 184."

I would appreciate enormously any insight or recommendation.

1
  • The error is not happening where you indicate; that line will never generate that error. Figure out where the error is really happening. Commented May 15, 2016 at 17:12

2 Answers 2

4

The problem is with the splice that modifies the list while it is being processed. By using the 0..(scalar @leaderboard-1) you set up the range of elements to process at the beginning, but when some elements are removed by the splice, the list ends up shorter than that and once $i runs off the end of the modified list you get undefined references.

A quick fix would be to use

for (my $i = 0; $i < @leaderboard; $i++) 

although that's neither very idiomatic nor efficient. Note that doing something like $i < @leaderboard or @leaderboard-1 already provides scalar context for the array variable, so you don't need the scalar() call, it does nothing here.

I'd probably use something like

my @result;
while(my $elem = shift @leaderboard) {
    ...
    if ($w==$parentmass) {
        # do more stuff
        push @result, $elem;
    }
}

So instead of deleting from the original list, all elements would be taken off the original and only the successful (by whatever criterion) ones included in the result.

Sign up to request clarification or add additional context in comments.

Comments

1

There seem to be two things going on here

  • You're removing all arrays from @leaderboard whose sumaarray is greater than $parentmass

  • You're putting in @Leader the array with the highest score of all the arrays in @leaderboard whose sumaarray is equal to $parentmass

I'm unclear whether that's correct. You don't seem to handle the case where sumaarray is less than $parentmass at all. But that can be written very simply by using grep together with the max_by function from the List::UtilsBy module

use List::UtilsBy 'max_by';


my $parentmass = $spect[-1];

my @leaderboard = grep { sumaarray(@$_) <= $parentmass } @arrarraa;

my $leader = max_by { score(@$_) }
        grep { sumaarray(@$_) == $parentmass }
        @leaderboard;

I'm sure this could be made a lot neater if I understood the intention of your algorithm; especially how those elements with a sumarray of less that $parentmass

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.