Perl编程实践与技巧解析

内容分享2天前发布
1 0 0

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、在$second、$fourth和$sixth这些变量中,哪些变量的求值结果为真?如何让$fourth的求值结果为假?

在 Perl 里,非空字符串会被视为真。

$second

是一个空格字符串

$fourth

是字符串

'0.0'

$sixth

是字符串

'false'

它们都是非空字符串,求值结果都为真。

若要让

$fourth

求值为假,可将其赋值为空字符串或数字

0

,例如:


$fourth = '';  # 赋值为空字符串

或者


$fourth = 0;   # 赋值为数字 0

4、给定华氏温度数组@fahrenheit (0, 32, 65, 80, 212),创建对应的摄氏温度数组@celsius。

要将华氏温度转换为摄氏温度,需先减去32,再乘以5/9。以下是创建

@celsius

数组的代码:


my @fahrenheit = ( 0, 32, 65, 80, 212 );
my @celsius = map { ( $_ - 32 ) * 5 / 9 } @fahrenheit;

5、给定数组 @ids 为 (AAA bbb Ccc ddD EEE),将 @ids 数组元素全部转换为大写来创建数组 @upper。

可使用如下 Perl 代码:


my @ids = qw(AAA bbb Ccc ddD EEE);
my @upper = map { uc } @ids;

上述代码使用

map

函数和

uc

函数将 @ids 数组元素全部转换为大写后赋值给 @upper 数组。

6、如何创建一个哈希,键为水果名称,值为它们的正常颜色,并将每个键值对作为单独的一行打印出来,格式类似于“bananas are yellow”?

可以使用以下代码实现:


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
";
}

7、判断 $second, $fourth, 和 $sixth 是否都为真。其中 $fourth 是字符串 ‘0.0’,如何让它为假以及如何判断这三个变量是否都为真?

在 Perl 里,字符串形式的

'0.0'

会被视作假值。要判断

$second


$fourth


$sixth

是否都为真,可使用逻辑与运算符

&&

。示例代码如下:


if ($second && $fourth && $sixth) {
    print '都为真';
} else {
    print '并非都为真';
}

由于

$fourth


'0.0'

字符串,本身就会被当作假值处理。

8、如何创建 @celsius 数组,已知 @fahrenheit 数组为 ( 0, 32, 65, 80, 212 ) ?

要创建

@celsius

数组,需将

@fahrenheit

数组中的华氏温度转换为摄氏温度。转换公式是先减去 32,再乘以 5/9。代码示例如下:


my @fahrenheit = ( 0, 32, 65, 80, 212 );
my @celsius = map { ( $_ - 32 ) * 5 / 9 } @fahrenheit;

9、已知 @ids 数组为 qw(AAA bbb Ccc ddD EEE) ,如何创建 @upper 数组,使得 @upper 数组包含 @ids 数组中所有元素转换为大写后的结果?

可以使用以下代码创建

@upper

数组,该数组包含

@ids

数组中所有元素转换为大写后的结果:


@upper = map { uc } @ids;

这里使用了

map

函数和

uc

函数,

uc

函数用于将字符串转换为大写,

map

函数会对

@ids

数组中的每个元素应用

uc

函数,并将结果存储在

@upper

数组中。

10、如何让代码打印的 1 到 10 数字在单独的行上?

在大多数编程语言中,可使用循环结合换行符来实现。例如在 Python 中:


for i in range(1, 11):
    print(i)

在 Java 中:


public class Main {
    public static void main(String[] args) {
        for (int i = 1; i <= 10; i++) {
            System.out.println(i);
        }
    }
}

11、已知 @numbers 数组为 qw< 3 9 0 7 8 >,如何计算数组元素的总和?

可以编写一个子函数来计算数组元素的总和,示例代码如下:


sub sum {
    my @numbers = @_;
    my $total = 0;
    $total += $_ foreach @numbers;
    return $total;
}

my @numbers = qw< 3 9 0 7 8 >;
my $sum = sum(@numbers);
print $sum;

上述代码定义了一个名为

sum

的子函数,它接受一个数组作为参数,然后遍历数组中的每个元素并累加到

$total

变量中,最后返回总和。

12、分析代码打印结果,若想让数字在单独行输出应如何修改,代码功能为打印 1 到 10 的数字

由于未给出具体代码,假设代码是用 Python 实现打印 1 到 10 的数字,常见代码可能是:


print([i for i in range(1, 11)])

此代码会将 1 到 10 的数字以列表形式在一行输出。若想让数字在单独行输出,可修改为:


for i in range(1, 11):
    print(i)

若使用其他编程语言,思路类似,通过循环逐个打印数字并换行。

13、计算数组元素的总和与平均值并打印输出,数组为 @numbers = (3, 9, 0, 7, 8)

可以使用以下代码来实现:


sub average {
    my @numbers = @_;
    my $total = 0;
    $total += $_ foreach @numbers;
    my $average = $total / @numbers;
    print "总和为 $total,平均值为 $average
";
}

average(3, 9, 0, 7, 8);

这段代码定义了一个名为

average

的子程序,它接收一个数组作为参数。在子程序中,首先将数组元素的总和计算出来,然后计算平均值,并将总和与平均值打印输出。最后调用这个子程序并传入指定的数组。

14、补全代码,为哈希表 %stat_for 中每个键赋随机值,随机值需大于等于 6 并打印结果

以下是补全后的代码,可以实现为哈希表

%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

在代码里,借助

foreach

循环遍历哈希表中的每个键,利用

do - while

循环生成随机数,直至随机数大于等于 6,再将该随机数赋值给对应的键,最后打印出哈希表的内容。

15、编写一个子例程计算传入数字的平均值,并打印出 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);

这段代码定义了一个名为

average

的子例程,用于计算传入数字的平均值。在子例程中,会检查每个传入的参数是否为数字,如果不是则抛出错误。最后,代码调用

average

子例程计算并打印出 1、5、18、3、5 的平均值。

16、编写代码实现计算传入数字的平均值(如传入 1 5 18 3 5 计算其平均值)

以下是使用 Python 实现计算传入数字平均值的代码:


numbers = [1, 5, 18, 3, 5]
result = sum(numbers) / len(numbers)
print(result)

在上述代码中,首先定义了一个包含数字的列表

numbers

,然后使用

sum()

函数计算列表中所有数字的总和,使用

len()

函数获取列表的长度,最后将总和除以长度得到平均值并打印输出。如果要传入不同的数字,只需修改

numbers

列表的内容即可。

如果你使用的是其他编程语言,如 Java,代码示例如下:


import java.util.Arrays;

public class AverageCalculator {
    public static void main(String[] args) {
        int[] numbers = {1, 5, 18, 3, 5};
        int sum = 0;
        for (int number : numbers) {
            sum += number;
        }
        double average = (double) sum / numbers.length;
        System.out.println(average);
    }
}

在 Java 代码中,定义了一个整数数组

numbers

,通过

for-each

循环遍历数组计算总和,将总和转换为

double

类型后除以数组长度得到平均值并打印输出。

17、编写一个平均函数,要求检查传入的参数是否为数字,若不是则抛出异常

以下是使用 Python 实现的平均函数示例:


def average(*args):
    for num in args:
        if not isinstance(num, (int, float)):
            raise ValueError(f'{num} 不是有效的数字。')
    if not args:
        return 0
    return sum(args) / len(args)

你可以使用以下方式调用这个函数:


result = average(1, 2, 3, 4)
print(result)

如果传入非数字参数,函数会抛出

ValueError

异常。

18、编写一个函数 make_multiplier,它接受一个数字作为参数,返回一个新的函数,新函数接受一个参数并返回该参数与 make_multiplier 传入数字的乘积

以下是使用 Perl 语言实现的代码:


sub make_multiplier {
    my $number = shift;
    return sub {
        return shift(@_) * $number;
    };
}

你可以使用以下方式调用这个函数:


my $times_seven = make_multiplier(7);
my $times_five  = make_multiplier(5);

print 21 == $times_seven->(3) ? "yes
" : "no
";
print 20 == $times_five->(4) ? "yes
" : "no
";

19、编写一个递归函数 sum 用于计算传入参数的总和

以下是实现该功能的代码:


sub sum {
    return 0 unless @_;
    my ( $head, @tail ) = @_;
    return $head + sum(@tail);
}

20、编写一个正则表达式来匹配美国社会保障号码,格式为 ###-##-####,并使用单词边界。

d{3}-d{2}-d{4}

21、给定一段包含员工姓名和员工编号的文本,员工姓名仅由字母组成,员工编号是五位数,编写一个正则表达式来提取员工姓名和对应的员工编号。

可以使用正则表达式

/([a-zA-Z]+)s*:s*(d{5})/

来提取员工姓名和对应的员工编号。其中:

([a-zA-Z]+)

用于匹配仅由字母组成的员工姓名

(d{5})

用于匹配五位数的员工编号

s*

用于匹配可能存在的空白字符

22、编写一个程序,从标准输入读取内容并打印出来。

在Perl中可以使用如下代码实现从标准输入读取内容并打印出来:


use strict;
use warnings;
while (my $line = <STDIN>) {
    print $line;
}

将上述代码保存为一个

.pl

文件,例如

read_stdin.pl

,然后在命令行使用

perl read_stdin.pl

运行该程序,之后输入内容,按回车键,程序会将输入的内容打印出来。输入完成后,可使用

Ctrl + D

(在Windows上是

Ctrl + Z

)结束输入。

23、编写一个函数 average,该函数接受任意数量的参数,计算这些参数的平均值。如果参数中包含非数字,抛出异常。

以下是实现该功能的代码:


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;
}

24、编写一个函数 make_multiplier,该函数接受一个数字作为参数,返回一个新的函数,新函数接受一个参数并返回该参数与原函数参数的乘积。

以下是实现该功能的代码:


sub make_multiplier {
    my $number = shift;
    return sub {
        return shift(@_) * $number;
    };
}

使用示例:


my $times_seven = make_multiplier(7);
my $times_five = make_multiplier(5);

print 21 == $times_seven->(3) ? "yes
" : "no
";
print 20 == $times_five->(4) ? "yes
" : "no
";

25、编写一个递归函数 sum,该函数接受任意数量的参数,计算这些参数的总和。

以下是实现此功能的代码:


sub sum {
    return 0 unless @_;
    my ( $head, @tail ) = @_;
    return $head + sum(@tail);
}

26、请编写代码实现从标准输入读取内容并打印

在 Perl 中,可以使用以下代码实现从标准输入读取内容并打印:


while (my $line = <STDIN>) {
    print $line;
}

上述代码使用

while

循环和

<STDIN>

来逐行读取标准输入的内容,然后使用

print

函数将每行内容打印出来。

27、编写代码实现从标准输入读取内容,跳过只包含空白字符的行和以 # 开头的注释行,然后打印剩余内容

以下是使用 Python 实现该功能的代码:


import sys
for line in sys.stdin:
    line = line.strip()
    if line and not line.startswith('#'):
        print(line)

这段代码从标准输入逐行读取内容,去除每行首尾的空白字符,若该行不为空且不以

#

开头,则将其打印输出。

28、编写代码,将命令行参数中的每个单词拆分为字符,然后打印每个字符的 Unicode 码点(考虑 UTF – 8 编码)

以下是实现该功能的 Perl 代码:


#!/usr/bin/perl
use strict;
use warnings;
use Encode 'decode_utf8'; # 确保输入按 UTF-8 处理
@ARGV = map { decode_utf8($_) } @ARGV;

foreach my $word (@ARGV) {
    my @chars = split //, $word;
    foreach my $char (@chars) {
        my $codepoint = ord($char);
        print "字符: $char, Unicode 码点: U+", sprintf("%04X", $codepoint), "
";
    }
}

将上述代码保存为一个

.pl

文件,例如

unicode_codepoints.pl

,然后在命令行中运行,传入参数,如:


perl unicode_codepoints.pl 你好 World

即可看到每个字符及其对应的 Unicode 码点。

29、编写代码,将命令行参数中的每个单词拆分为字符,然后打印每个字符的 Unicode 码点(考虑 UTF – 8 编码),并将码点格式化为 U+XXXX 的形式

以下是实现该功能的 Perl 代码:


#!/usr/bin/perl
use strict;
use warnings;
use utf8;

foreach my $arg (@ARGV) {
    my @chars = split //, $arg;
    foreach my $char (@chars) {
        my $codepoint = sprintf("U+%04X", ord($char));
        print $codepoint, "
";
    }
}

这段代码会遍历命令行参数,将每个参数拆分为字符,然后打印每个字符的 Unicode 码点,格式为

U+XXXX

30、使用sort、map和grep来处理@employees数组。grep应筛选出服务年限超过1年的员工,sort应按姓氏对剩余员工进行排序,map应创建一个包含全名(名和姓)的数组。此外,使用for循环和排序子程序重写该解决方案。

以下是使用

sort


map


grep

的解决方案:


my @employees = (
    {
        first_name => 'Sally',
        last_name  => 'Jones',
        years      => 4,
        payscale   => 4,
    },
    {
        first_name => 'Abby',
        last_name  => 'Hoffman',
        years      => 1,
        payscale   => 10,
    },
    {
        first_name => 'Jack',
        last_name  => 'Johnson',
        years      => 4,
        payscale   => 5,
    },
    {
        first_name => 'Mr.',
        last_name  => 'Magnate',
        years      => 12,
        payscale   => 1,
    },
);

my @full_names = sort { $a->{last_name} cmp $b->{last_name} }
                 map  { $_->{first_name} . ' ' . $_->{last_name} }
                 grep { $_->{years} > 1 } @employees;

使用

for

循环和排序子程序的重写方案:


sub sort_by_last_name {
    $a->{last_name} cmp $b->{last_name};
}

my @filtered_employees;
for my $employee (@employees) {
    if ($employee->{years} > 1) {
        push @filtered_employees, $employee;
    }
}

my @sorted_employees = sort sort_by_last_name @filtered_employees;

my @full_names_loop;
for my $employee (@sorted_employees) {
    push @full_names_loop, $employee->{first_name} . ' ' . $employee->{last_name};
}
© 版权声明

相关文章

暂无评论

none
暂无评论...