table {
border-collapse: collapse;
width: 100%;
margin-bottom: 1rem;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
pre {
background-color: #f8f8f8;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
}
1、创建一个包含值 Andrew、Andy 和 Kaufman 的数组,并编写一个程序来打印 Andrew “Andy” Kaufman。
以下是实现此功能的 Perl 代码:
use strict;
use warnings;
my @array = ('Andrew', 'Andy', 'Kaufman');
print $array[0]. ' “'. $array[1]. '” '. $array[2]. "
";
上述代码首先创建了一个包含指定值的数组,然后通过索引访问数组元素并按要求的格式打印出来。
2、创建一个哈希,键为水果名称,值为它们的常见颜色,然后将每个键/值对作为单独的一行打印出来,格式类似于“香蕉是黄色的”。
以下代码展示了如何实现:
use strict;
use warnings;
use diagnostics;
my %color_for = (
bananas => 'yellow',
apples => 'red',
oranges => 'orange',
);
for my $fruit (keys %color_for) {
my $color = $color_for{$fruit};
print "$fruit are $color
";
}
3、根据华氏温度数组 @fahrenheit (0, 32, 65, 80, 212) 创建摄氏温度数组 @celsius。
要创建
@celsius
数组,需要将
@fahrenheit
数组中的每个华氏温度值转换为摄氏温度值。转换公式是先减去 32,然后乘以 5/9。以下是实现代码:
my @fahrenheit = ( 0, 32, 65, 80, 212 );
my @celsius = map { ( $_ - 32 ) * 5 / 9 } @fahrenheit;
4、给定一个包含华氏温度值的数组,创建一个新数组@celsius,其中包含转换为摄氏度的华氏温度。记住,要将华氏温度转换为摄氏温度,必须先减去32,然后将结果乘以5/9。
可以使用以下代码创建
@celsius
数组:
my @fahrenheit = ( 0, 32, 65, 80, 212 );
my @celsius = map { ($_ - 32) * 5/9 } @fahrenheit;
5、如何计算数组@numbers中元素的总和
可以使用如下代码:
my @numbers = qw< 3 9 0 7 8 >;
my $total = 0;
$total += $_ foreach @numbers;
6、如何让代码打印的1 – 10数字在不同行输出
在许多编程语言中,可使用循环结合换行符来实现。以Python为例,代码如下:
for i in range(1, 11):
print(i)
在上述代码中,
range(1, 11)
生成从1到10的整数序列,
print(i)
会将每个数字打印到单独一行。
7、编写代码计算数组@numbers中元素的总和与平均值并输出
以下是使用 Perl 语言实现计算数组
@numbers
中元素总和与平均值并输出的代码:
my @numbers = (28, 49, 1000, 4, 25, 49, 529);
my $sum = 0;
foreach my $num (@numbers) {
$sum += $num;
}
my $average = $sum / scalar(@numbers);
print "总和: $sum
";
print "平均值: $average
";
对于不同的数组元素,只需修改
@numbers
中的值即可。
8、找出代码中C – style for循环的逻辑错误并改正
代码中第一个 C – style for 循环示例打印 0 到 9,逻辑正确;第二个循环逻辑有问题,它打印的是 1 到 10,而非 0 到 9。错误在于先执行了
$i++
再打印。改正方法是先打印
$i
再执行
$i++
,修改后的代码如下:
my $i = 0;
for ( ; $i < 10; ) {
print "$i
";
$i++;
}
9、在代码中,对哈希表%stat_for中每个键对应的值进行随机赋值,随机值的生成规则为:将两个1 – 6的随机整数相加再加2,且随机值需大于等于6。请添加相应代码实现该功能。
foreach my $stat (keys %stat_for) {
my $random = 2 + int(rand(6)) + int(rand(6));
redo if $random < 6;
$stat_for{$stat} = $random;
}
10、编写完整代码,对哈希表%stat_for中每个键对应的值进行随机赋值,若随机值小于6则重新赋值,并输出结果
my %stat_for = ( strength => undef, intelligence => undef, dexterity => undef, );
foreach my $stat (keys %stat_for) {
my $random;
do {
$random = 2 + int(rand(6)) + int(rand(6));
} while ($random < 6);
$stat_for{$stat} = $random;
}
print <<"END_CHARACTER";
Strength: $stat_for{strength}
Intelligence: $stat_for{intelligence}
Dexterity: $stat_for{dexterity}
END_CHARACTER
11、使用两种方式创建数组并赋值,一种不使用分组括号,另一种使用逗号创建列表
在Perl中,不使用分组括号创建数组并赋值可直接用
qw
快捷方式,如:
@array = qw(value1 value2 value3);
使用逗号创建列表来赋值数组的方式为:
@array = ('value1', 'value2', 'value3');
12、对于给定的分数哈希表,如何使用不同方法获取 Jim 和 Mary 的分数,以及分析使用切片时的问题和解决办法
给定分数哈希表如下:
my $score_for = { jim => 89, mary => 73, alice => 100, bob => 83 };
获取 Jim 和 Mary 分数的方法有两种:
使用切片:
perl
my ( $jim, $mary ) = @$score_for{ qw{jim mary} };
print "$jim $mary";
单独赋值:
perl
$jim = $score_for->{jim};
$mary = $score_for->{mary};
print "$jim $mary";
使用切片时的问题:写
%$score_for{ ... }
是错误的。
解决办法:
使用
@
符号表示获取变量列表,如
@$score_for{ ... }
;
不使用切片,而是单独赋值,许多程序员认为这种方法更简洁。
13、编写一个子程序来计算传入数字的平均值,并计算 1、5、18、3、5 这些数字的平均值
以下是实现该功能的代码:
use Scalar::Util 'looks_like_number';
use Carp 'croak';
sub average {
my @numbers = @_;
my $total = 0;
foreach my $number (@numbers) {
if ( not looks_like_number($number) ) {
croak "$number doesn't look like a number";
} else {
$total += $number;
}
}
return $total / @numbers;
}
print average(1, 5, 18, 3, 5);
14、编写一个子程序,该子程序接受一个数字作为参数,并返回一个新的子程序,新子程序接受一个数字并返回该数字与原参数的乘积
以下是使用 Perl 实现该功能的代码:
sub multiplier_factory {
my $factor = shift;
return sub {
my $number = shift;
return $number * $factor;
};
}
使用示例:
my $multiply_by_five = multiplier_factory(5);
print $multiply_by_five(3); # 输出 15
15、编写一个递归子程序来计算一组数字的总和
以下是使用 Perl 编写的递归子程序来计算一组数字的总和的示例代码:
sub sum_recursive {
my @numbers = @_;
if (scalar @numbers == 0) {
return 0;
} else {
my $first = shift @numbers;
return $first + sum_recursive(@numbers);
}
}
# 测试代码
my @nums = (1, 2, 3, 4, 5);
my $result = sum_recursive(@nums);
print $result; # 输出 15
在这个代码中,
sum_recursive
子程序接收一组数字作为参数。如果输入的数组为空,它返回 0;否则,它取出数组的第一个元素,并递归调用自身来计算剩余元素的总和,最后将第一个元素与剩余元素的总和相加。
16、编写一个程序,从标准输入读取内容并打印出来
在 Perl 中可以使用如下简单程序实现从标准输入读取内容并打印出来:
use strict;
use warnings;
while (my $line = <STDIN>) {
print $line;
}
将上述代码保存为一个
.pl
文件,例如
read_print.pl
,然后在命令行中运行
perl read_print.pl
,之后输入内容,按回车键即可看到输入的内容被打印出来,输入结束后可以按
Ctrl + D
(在 Windows 系统中按
Ctrl + Z
然后回车)结束输入。
17、对数组 ( 0x23, 0xAA, 0xaa, 0x01, 0xfB ) 进行降序数字排序,并考虑以十六进制形式输出排序结果
在大多数编程语言中,可先将十六进制数转换为十进制进行排序,再转换回十六进制输出。以 Python 为例,代码如下:
arr = [0x23, 0xAA, 0xaa, 0x01, 0xfB]
arr.sort(reverse=True)
hex_arr = [hex(num) for num in arr]
print(hex_arr)
运行结果为
['0xfb', '0xaa', '0xaa', '0x23', '0x1']
。
18、从数组 @list 中找出唯一的元素
可使用
grep
语句实现。示例代码如下:
my @list = qw( bob sally Andromalius sally bob ned Andromalius );
my %seen;
my @unique_list = grep {!$seen{$_}++ } @list;
最终
@unique_list
数组中即为唯一的元素。
19、对数组 @employees 进行筛选(工作年限大于 1 年)、排序(按姓氏排序),并将结果转换为 ‘名字 姓氏’ 的形式,同时用 for 循环实现该功能。
以下是使用 for 循环重写的代码:
sub by_last_name {
$a->{last_name} cmp $b->{last_name}
};
my @names = ();
my @sorted_employees = sort by_last_name @employees;
for my $employee (@sorted_employees) {
if ($employee->{years} > 1) {
push @names, "$employee->{first_name} $employee->{last_name}";
}
}
这段代码首先定义了按姓氏排序的子程序
by_last_name
,然后对
@employees
数组进行排序得到
@sorted_employees
。接着使用 for 循环遍历排序后的数组,筛选出工作年限大于 1 年的员工,并将其名字和姓氏组合成字符串添加到
@names
数组中。
20、添加 Convert::Distance::Metric 后,lib/ 目录应呈现怎样的文件布局
lib/
└── Convert
└── Distance
├── Imperial.pm
└── Metric.pm
21、编写一个名为Convert::Distance::Metric的模块,该模块包含以下子例程:kilometers_to_meters(公里转米)、meters_to_kilometers(米转公里)。使这些子例程可选择性导出,并且允许人们使用
use Convert::Distance::Metric ":all";
导入所有子例程。
use Convert::Distance::Metric ":all";
package Convert::Distance::Metric;
use strict;
use warnings;
our $VERSION = '0.01';
use Exporter 'import';
our @EXPORT_OK = qw( kilometers_to_meters meters_to_kilometers );
our %EXPORT_TAGS = ( all => @EXPORT_OK );
use constant METERS_PER_KILOMETER => 1000;
sub meters_to_kilometers {
my $meters = shift;
return $meters / METERS_PER_KILOMETER;
}
sub kilometers_to_meters {
my $kilometers = shift;
return $kilometers * METERS_PER_KILOMETER;
}
1; # Don’t forget that trailing 1!
22、添加Convert::Distance::Metric后,查看lib/目录的文件布局以及MANIFEST的内容。
添加Convert::Distance::Metric后,lib/目录的文件布局如下:
lib/
└── Convert/
└── Distance/
├── Imperial.pm
└── Metric.pm
MANIFEST内容如下:
Changes
lib/Convert/Distance/Imperial.pm
lib/Convert/Distance/Metric.pm
Makefile.PL
MANIFEST
README
t/00-load.t
t/manifest.t
t/pod-coverage.t
t/pod.t
23、在Convert::Distance::Metric模块中添加完整的POD文档,包含以下部分:模块名称(NAME)、简要代码片段展示使用方法(SYNOPSIS)、模块用途描述(DESCRIPTION)、模块导出内容的可选列表(EXPORT)、每个子例程的详细描述(FUNCTION)、已知的错误及如何报告新错误(BUGS)、指向Convert::Distance::Imperial的链接(SEEALSO)、模块作者(AUTHOR)、模块的许可条款(LICENSE)。并通过perldoc lib/Convert/Distance/Metric.pm验证POD输出,也可运行podchecker lib/Convert/Distance/Metric.pm检查POD中的错误。
在模块中添加如下POD内容:
__END__
=head1 NAME
Convert::Distance::Metric - Convert kilometers to meters and back
=head1 SYNOPSIS
use Convert::Distance::Metric ":all";
print kilometers_to_meters(7);
print meters_to_kilometers(3800);
=head1 DESCRIPTION
This is a simple module to convert kilometers to meters and back. It’s mainly here to show how modules are built and documented.
=head1 EXPORT
The following functions may be exported on demand. You can export all of them with:
use Convert::Distance::Metric ':all';
=over 4
=item kilometers_to_meters
Converts kilometers to meters.
=item meters_to_kilometers
Converts meters to kilometers.
=back
=head1 BUGS
No known bugs at this time.
=head1 SEE ALSO
L<Convert::Distance>, L<perlfunc>
=head1 AUTHOR
Your Name <your.email@example.com>
=head1 LICENSE
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
还需添加FUNCTION、BUGS、SEEALSO、AUTHOR、LICENSE等部分的具体内容,之后使用
perldoc lib/Convert/Distance/Metric.pm
验证POD输出,运行
podchecker lib/Convert/Distance/Metric.pm
检查POD错误。
24、编写一个简短的程序,将3.5千米转换为米,并将结果再转换回千米。假设存在一个名为Convert::Distance::Metric的模块,该模块提供了kilometers_to_meters和meters_to_kilometers两个函数,分别用于千米到米和米到千米的转换。
use Convert::Distance::Metric ":all";
my $meters = kilometers_to_meters(3.5);
my $kilometers = meters_to_kilometers($meters);
print "3.5千米转换为米是:$meters 米
";
print "转换回千米是:$kilometers 千米
";
25、编辑Convert – Distance – Imperial发行版中的t/00 – load.t测试程序,尝试添加一个测试来验证是否可以加载Convert::Distance::Metric模块。
可在
t/00 - load.t
中添加相关测试代码,然后使用
prove -lv t/00 - load.t
检查是否有效,或者运行
perl makefile.pl
make
make test
26、指出代码中 new() 构造函数存在的问题
在示例的
new()
构造函数中,使用了单参数的
bless
,即只对引用进行了祝福,但未指定将其祝福到哪个类中。此时,Perl 会将对象祝福到当前包中,这被认为是不良形式。因为后续若需要从该类继承并复用
new()
构造函数时,会因它将引用祝福到当前类而无法实现。
27、请编写一个 User 类,要求包含 username 和 password 属性,password 属性需要进行 MD5 加密,并且提供一个方法用于验证密码是否正确。
package User;
use Moose;
use Digest::MD5 'md5_hex';
use namespace::autoclean;
has username => ( is => 'ro', isa => 'Str', required => 1 );
has password => ( is => 'ro', isa => 'Str', writer => '_set_password', );
sub BUILD {
my $self = shift;
$self->_set_password(md5_hex($self->password));
}
sub password_eq {
my ( $self, $password ) = @_;
$password = md5_hex($password);
return $password eq $self->password;
}
__PACKAGE__->meta->make_immutable;
1;
28、编写一个 unique 函数,该函数接受一个数组作为参数,返回数组中唯一的元素,并且元素的顺序应该与它们在原始数组中出现的顺序相同。
以下是实现该功能的代码:
sub unique {
my @array = @_;
my %seen;
my @unique;
foreach my $element (@array) {
push @unique, $element unless $seen{$element}++;
}
return @unique;
}
29、原 unique 函数返回的元素顺序是随机的,如何修改代码使它返回的元素按顺序排列。
可以使用哈希表和数组结合的方式来实现。代码示例如下:
my @array = ( 3, 4, 1, 4, 7, 7, 4, 1, 3, 8 );
my %seen;
my @ordered;
foreach my $element (@array) {
if ( not $seen{$element}++ ) {
push @ordered, $element;
}
}
foreach my $element (@ordered) {
print "Ordered: $element
";
}
这段代码通过遍历数组,利用哈希表
%seen
标记元素是否已出现过,将首次出现的元素按顺序存入数组
@ordered
中,从而实现按顺序输出唯一元素。