sliddy sliddy - 3 months ago 7
Perl Question

Perl function to find the longest word from each separate array

I have a task:

There are several arrays, each element of which is a word. Create a function which finds the longest word from each given array and returns the result as a list. References to arrays should be passed as arguments to the function.

This function gives me the longest word from two arrays. I just didn't get it how to make it find the longest words from each separate array.

use strict;
my @arr1 = qw/one two three/;
my @arr2 = qw/four five seven/;
my $arr1 = \@arr1;
my $arr2 = \@arr2;
my @sorted_words;

sub func {
for (@_) {
for (@$_){
@sorted_words = sort {length($b) <=> length ($a)} $_;}
}
print "The longest word is: $sorted_words[0]\n";
}
func($arr1, $arr2);

Answer

The answer to this question is already in the "Nested loops" section of the first lecture of any first introduction to algorithms course...

The basic algorithm for finding the "best" value in an array according to some parameter is:

best ← worst possible value
for each value in array
    if value is better than best
        then best ← value
    end if
end for each

What you want is the longest string, so the worst case is an empty string. In Perl, that would give you:

my @array = qw/one two three/;
my $best = '';
for my $value (@array) {
    if (length $value > length $best) {
        $best = $value;
    }
}

If you want to do this for many arrays, just add an additional outer loop:

best_array ← ()
for each array in array_of_array
    best ← worst possible value
    for each value in array
        if value is better than best
            then best ← value
        end if
    end for each
    best_array ← best_array, best
end for each

Or, in Perl:

my @arr1 = qw/one two three/;
my @arr2 = qw/four five seven/;
my @arr3 = qw/six eight nine/;
my @array_of_arrays = (\@arr1, \@arr2, \@arr3);
my @longest_words;

for my $array (@array_of_arrays) {
    my $best = '';
    for my $value (@$array) {   # notice "@$" to dereference the array
        if (length $value > length $best) {
            $best = $value;
        }
    }
    push @longest_words, $best;
}

Update: subroutine

I have just realised the question specifically asked for a subroutine. The code above is easy to change into a subroutine:

my @arr1 = qw/one two three/;
my @arr2 = qw/four five seven/;
my @arr3 = qw/six eight nine/;
my @array_of_arrays = (\@arr1, \@arr2, \@arr3);

sub funct {
    my @longest_words;
    for my $array (@_) {
        my $best = '';
        for my $value (@$array) {   # notice "@$" to dereference the array
            if (length $value > length $best) {
                $best = $value;
            }
        }
        push @longest_words, $best;
    }
    return @longest_words;
}

my @longest_words = funct(@array_of_arrays);
Comments