我有一个任务:
有几个数组,每个数组都是一个单词。创建一个函数,该函数从每个给定数组中查找最长的单词,并将结果作为列表返回。对数组的引用应作为参数传递给函数。
这个函数给了我两个数组中最长的单词。我只是没有得到如何让它找到每个单独数组中最长的单词。
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);
答案 0 :(得分:3)
这个问题的答案已经出现在算法课程首次介绍的第一讲的“嵌套循环”部分......
根据某个参数查找数组中“最佳”值的基本算法是:
best ← worst possible value
for each value in array
if value is better than best
then best ← value
end if
end for each
你想要的是最长的字符串,所以最坏的情况是空字符串。在Perl中,这会给你:
my @array = qw/one two three/;
my $best = '';
for my $value (@array) {
if (length $value > length $best) {
$best = $value;
}
}
如果要对许多数组执行此操作,只需添加一个额外的外部循环:
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
或者,在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;
}
更新:子程序
我刚刚意识到问题特别要求子程序。上面的代码很容易变成子程序:
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);
答案 1 :(得分:2)
这个问题要求你提供一个函数&#34;将结果作为列表&#34; 返回,所以在函数内打印答案不是答案。
您需要逐个处理数组并跟踪到目前为止找到的所有最长的单词,然后在结尾处将它们全部返回。
这样的事情很好:
use strict;
use warnings;
my @arr1 = qw/one two three/;
my @arr2 = qw/four five seven/;
sub func {
my @max;
for my $list (@_) {
my @sorted = sort { length($b) <=> length ($a) } @$list;
push @max, $sorted[0];
}
@max;
}
my @longest = func(\@arr1, \@arr2);
printf "The longest words are: %s\n", join ', ', @longest;
The longest words are: three, seven
但我会编写一个子程序,从一个数组中返回最长的单词,然后使用map
创建所有最长单词的列表。
看起来像这样
use strict;
use warnings;
my @arr1 = qw/one two three/;
my @arr2 = qw/four five seven/;
sub longest {
my ($list) = @_;
my $longest = '';
for (@$list) {
$longest = $_ if length > length($longest);
}
$longest;
}
sub func {
map longest($_), @_;
}
my @longest = func(\@arr1, \@arr2);
printf "The longest words are: %s\n", join ', ', @longest;
答案 2 :(得分:1)
另一种解决方案是使用数组或数组数组来调用函数。如果用后者调用,只需递归调用函数来获取值。
以下内容可以使用List::Util reduce
来确定最大length
元素。
use strict;
use warnings;
use List::Util qw(reduce);
my @AoA = (
[qw(one two three)],
[qw(four five seven)],
[qw(six eight nine)],
);
sub longest {
return map {longest(@$_)} @_ if ref $_[0];
return reduce {length $b > length $a ? $b : $a} @_;
}
my @longest_words = longest(@AoA);
print "@longest_words\n";
输出:
three seven eight
答案 3 :(得分:-2)
如果你分别用每个数组调用子程序,它将按照你想要的方式工作。
使用
func($arr1);
func($arr2);
而不是:
func($arr1, $arr2);
顺便说一句,你现在应该只对一个数组正常工作。尝试通过将@ arr1重命名为@ arr2并将@ arr2重命名为@ arr1来更改数组名称并运行原始程序。