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、当方括号内的数字2出现在练习题文本开头时,它意味着什么?
这个数字是对完成该特定练习题所需时间的大致估计,单位为分钟。
不过这只是粗略估计,实际完成时间可能是该数字的一半,也可能是两倍。
2、编写并运行一个输出“Hello, world”的Perl程序,以测试Perl环境是否可以正常工作。
以下几种方式可实现“Hello, world”程序:
创建文件,在文件中编写代码:
– 若使用Perl 5.10之前版本,代码为:
perl
print "Hello, world!
";
– 若使用Perl 5.10或更高版本,代码为:
perl
use 5.010;
say "Hello, world!";
然后运行该文件。
从命令行运行,不创建文件:
– 使用
-e
开关,命令为:
bash
$ perl -e 'print "Hello, World
"'
– 使用
-l
开关,命令为:
bash
$ perl -le 'print "Hello, World"'
编写脚本文件:
perl
#!/usr/bin/perl
use 5.010;
say "Hello World!";
该脚本仅能在Perl 5.10或更高版本运行。
3、编写一个程序,计算半径为 12.5 的圆的周长。圆的周长是 2π乘以半径(约为 2 乘以 3.141592654)。你得到的答案应该约为 78.5。
#!/usr/bin/perl -w
$pi = 3.141592654;
$circ = 2 * $pi * 12.5;
print "The circumference of a circle of radius 12.5 is $circ.
";
4、编写一个程序,提示用户输入圆的半径,然后根据输入的半径计算并输出该圆的周长。若用户输入的半径为负数,则周长输出为 0。
#!/usr/bin/perl -w
$pi = 3.141592654;
print "What is the radius? ";
chomp($radius = <STDIN>);
$circ = 2 * $pi * $radius;
if ($radius < 0) {
$circ = 0;
}
print "The circumference of a circle of radius $radius is $circ.
";
5、编写一个程序,让用户输入一个圆的半径,程序计算并输出该圆的周长。如果用户输入的半径数字小于零,报告的周长将为零,而不是负数。
以下是修改后的程序示例:
#!/usr/bin/perl -w
$pi = 3.141592654;
print "What is the radius? ";
chomp($radius = <STDIN>);
$circ = 2 * $pi * $radius;
if ($radius < 0) {
$circ = 0;
}
print "The circumference of a circle of radius $radius is $circ.
";
该程序会先提示用户输入半径,然后计算周长。若输入的半径小于零,会将周长设为零,最后输出结果。
6、编写一个程序,提示用户输入两个数字(分别在两行输入),并输出这两个数字相乘的结果。
以下是实现该功能的 Perl 代码示例:
print "Enter the first number: ";
chomp($num1 = <STDIN>);
print "Enter the second number: ";
chomp($num2 = <STDIN>);
$result = $num1 * $num2;
print "The product of the two numbers is: $result
";
该代码首先提示用户输入第一个数字,将其存储在
$num1
中,接着提示输入第二个数字,存储在
$num2
中,然后计算两数乘积并输出结果。
7、编写一个程序,提示用户输入一个字符串和一个数字(分别在不同的输入行),并按照数字指定的次数将字符串打印在不同的行上。(提示:使用 x 运算符)。如果用户输入“fred”和“3”,输出应该是三行,每行都显示“fred”。如果用户输入“fred”和“299792”,可能会有大量输出。
以下是实现该功能的程序:
print "Enter a string: ";
$str = <STDIN>;
print "Enter a number of times: ";
chomp($num = <STDIN>);
$result = $str x $num;
print "The result is:
$result";
该程序首先提示用户输入一个字符串和一个数字,然后使用
x
运算符将字符串重复指定的次数,最后将结果打印出来。需要注意的是,这里没有对输入的字符串进行
chomp
操作,因为题目要求字符串出现在不同的行上。
8、编写一个程序,逐行读取一系列数字,直到输入结束,然后针对每个数字,从下面的列表中打印出对应的人名。(将这个人名列表硬编码到你的程序中,即它应出现在程序的源代码里)。例如,如果输入的数字是 1、2、4 和 2,输出的人名将是 fred、betty、dino 和 betty。人名列表为:fred betty barney dino wilma pebbles bamm – bamm
以下是一个 Python 示例代码,可实现该功能:
names = ['fred', 'betty', 'barney', 'dino', 'wilma', 'pebbles', 'bamm - bamm']
while True:
try:
num = int(input())
if 1 <= num <= len(names):
print(names[num - 1], end=' ' if input().strip() else '')
else:
print(f'输入的数字 {num} 超出范围。')
except (EOFError, ValueError):
break
此代码首先定义了人名列表,接着通过循环持续读取输入的数字,把数字转换为索引来获取对应的人名并打印。若输入超出范围或非数字,会给出相应提示。当遇到输入结束信号或输入非数字时,循环终止。
9、编写一个名为 total 的子程序,它返回一个数字列表的总和。该子程序不应执行任何输入输出操作,仅处理其参数并将一个值返回给调用者。并使用以下代码测试该子程序:my @fred = qw{ 1 3 5 7 9 }; my $fred_total = total(@fred); print “The total of @fred is $fred_total.
”; print “Enter some numbers on separate lines: “; my $user_total = total(
); print “The total of those numbers is $user_total.
”; 第一组数字的总和应该是 25。
以下是实现
total
子程序的代码:
sub total {
my $sum = 0;
foreach (@_) {
$sum += $_;
}
return $sum;
}
这个子程序通过遍历传入的参数列表,将每个参数累加到
$sum
中,最后返回总和。为避免传入空列表时返回
undef
,将
$sum
初始化为
0
。
10、编写一个程序来计算 1 到 1000 的数字之和。
由于不清楚上一题子程序情况,这里给出通用 Python 代码示例:
result = sum(range(1, 1001))
print("The numbers from 1 to 1000 add up to", result, ".")
总和应为 500500。
11、编写一个名为 above_average 的子程序,它接受一个数字列表,并返回其中大于平均值(均值)的数字。(提示:编写另一个子程序,通过将总数除以项数来计算平均值。)在以下测试程序中测试你的子程序。my @fred = above_average(1..10); print “@fred is @fred
”; print “(Should be 6 7 8 9 10)
“; my @barney = above_average(100, 1..10); print “@barney is @barney
“; print “(Should be just 100)
“;
程序定义
首先需要定义一个计算总数的子程序
total
,然后定义计算平均值的子程序,最后定义
above_average
子程序。
示例代码
sub total {
my $sum = 0;
$sum += $_ for @_;
return $sum;
}
sub average {
my @list = @_;
return undef if !@list;
my $sum = total(@list);
return $sum / @list;
}
sub above_average {
my @list = @_;
my $average = average(@list);
my @result;
foreach my $element (@list) {
if ($element > $average) {
push @result, $element;
}
}
return @result;
}
my @fred = above_average(1..10);
print "@fred is @fred
";
print "(Should be 6 7 8 9 10)
";
my @barney = above_average(100, 1..10);
print "@barney is @barney
";
print "(Should be just 100)
";
12、编写一个名为 greet 的子程序,该子程序通过告知被问候者上一个被问候者的名字来欢迎此人。例如,执行 greet( “Fred” ); greet( “Barney” ); 这两条语句时,应输出:Hi Fred! You are the first one here! Hi Barney! Fred is also here!
以下是实现该功能的代码:
use 5.010;
greet( 'Fred' );
greet( 'Barney' );
sub greet {
state $last_name;
my $name = shift;
print "Hi $name! ";
if( defined $last_name ) {
print "$last_name is also here!
";
} else {
print "You are the first one here!
";
}
$last_name = $name;
}
13、修改之前的程序,让它在每次迎接新人时,告知其之前已迎接过的所有人的名字。执行以下语句序列:greet( “Fred” ); greet( “Barney” ); greet( “Wilma” ); greet( “Betty” ); 程序应该输出:Hi Fred! You are the first one here! Hi Barney! I’ve seen: Fred Hi Wilma! I’ve seen: Fred Barney Hi Betty! I’ve seen: Fred Barney Wilma
以下是修改后的程序:
use 5.010;
greet( 'Fred' );
greet( 'Barney' );
greet( 'Wilma' );
greet( 'Betty' );
sub greet {
state @names;
my $name = shift;
print "Hi $name! ";
if( @names ) {
print "I've seen: @names
";
} else {
print "You are the first one here!
";
}
push @names, $name;
}
14、编写一个程序,要求用户在不同的行输入一系列字符串,将每个字符串右对齐打印在一个20字符宽的列中。为确保输出列位置正确,同时打印一行数字作为“标尺”(这只是一个调试辅助手段)。要确保不会误使用19字符宽的列!例如,输入“hello”和“good – bye”,输出应类似如下:123456789012345678901234567890123456789012345678901234567890
hello
good – bye
以下是实现该功能的Perl代码示例:
print "Enter some lines, then press Ctrl - D (or Ctrl - Z on Windows):
";
chomp(my @lines = <STDIN>);
print "1234567890" x 6, "
";
foreach (@lines) {
printf "%20s
", $_;
}
代码解释:首先提示用户输入一系列字符串,按Ctrl – D(Windows系统按Ctrl – Z)结束输入。使用
chomp
函数去除输入字符串末尾的换行符,然后打印标尺行,最后使用
foreach
循环遍历输入的字符串数组,使用
printf
函数以右对齐、20字符宽的格式打印每个字符串。
15、修改程序,让用户可以选择列宽,这样输入30、hello、good – bye(分行输入)时,字符串将显示在第30列。额外加分项:当所选宽度较大时,让标尺线更长。
以下是实现该功能的代码:
print "What column width would you like? ";
chomp(my $width = <STDIN>);
print "Enter some lines, then press Ctrl-D:
"; # or Ctrl-Z
chomp(my @lines = <STDIN>);
print "1234567890" x (($width + 9)/10), "
"; # ruler line as needed
foreach (@lines) {
printf "%${width}s
", $_;
}
该程序先让用户输入列宽,然后让用户输入一些字符串,最后根据用户指定的列宽将字符串右对齐输出,并根据列宽生成合适长度的标尺线。
此外,还可以使用表达式
'%'.$width."s
"
生成格式字符串,或者使用
printf "%*s
", $width, $_;
的方式输出。
需要注意的是,要对输入的列宽使用
chomp
函数去除换行符,否则会影响格式字符串的生成。
16、编写一个程序,要求用户输入一个名字,若输入的名字为弗雷德、巴尼、威尔玛中的一个,则报告对应的姓氏,对应关系如下:弗雷德对应弗林特斯通,巴尼对应鲁布尔,威尔玛对应弗林特斯通;若输入的名字不是这三个,则提示未找到对应的姓氏。
以下是一个使用 Python 实现的示例代码:
name_dict = { "fred": "flintstone", "barney": "rubble", "wilma": "flintstone"}
user_name = input("请输入一个名字: ").lower()
if user_name in name_dict:
print(f"对应的姓氏是: {name_dict[user_name]}")
else:
print("未找到对应的姓氏。")
这段代码创建了一个字典来存储名字和姓氏的对应关系,然后获取用户输入的名字,检查该名字是否在字典中,如果存在则输出对应的姓氏,否则提示未找到。
17、编写一个程序,打印输入中提及“fred”的每一行(对于其他行不做处理)。如果输入字符串是“Fred”、“frederick”或“Alfred”,程序是否会匹配?创建一个包含几行提及“fred flintstone”及其朋友的小文本文件,然后将该文件作为此程序的输入。
要使程序匹配输入中提及“fred”的行,可使用正则表达式
/[fF]red/
。
正则表达式区分大小写,“
/fred/
”仅匹配“fred”。
若要匹配“Fred”等不同大小写形式,可用“
/[fF]red/
”。
对于“Fred”、“frederick”和“Alfred”,使用“
/[fF]red/
”能匹配,因为它们都包含“fred”。
示例代码如下:
while (<>) {
if (/[fF]red/) {
print;
}
}
可创建一个包含“fred flintstone”及其朋友的文本文件,将其作为输入运行此程序。
18、修改之前的程序,使其也能匹配“Fred”。如果输入字符串是“Fred”、“frederick”或“Alfred”,现在能匹配上吗?(将这些名字添加到文本文件中)
正则表达式区分大小写,原程序不匹配“Fred”,但修改程序后可以匹配。
修改方式是将之前程序使用的模式改为:
/[fF]red/
也可以尝试:
/(f|F)red/
/fred|Fred/
不过字符类方式更高效。
修改后能匹配“Fred”、“frederick”和“Alfred”,因为后两者都包含字符串“fred”。
19、编写一个程序,打印出每行中包含一个首字母大写但并非全大写单词的行。该程序会匹配 Fred,但不匹配 fred 或 FRED 吗?
可以将第一个练习答案中使用的模式改为
/[A-Z][a-z]+/
。此程序会匹配
Fred
,但不匹配
fred
或
FRED
,因为它匹配的是首字母大写且后续字母为小写的单词。
20、编写一个程序,打印出每行中包含两个相邻的相同非空白字符的行。该程序应能匹配包含如“Mississippi”、“Bamm – Bamm”或“llama”等单词的行。
示例代码如下:
while (<STDIN>) {
chomp;
if (/(S)1/) {
print $_ . "
";
}
}
上述代码中,
(S)
捕获一个非空白字符,
1
表示引用前面捕获的字符,即要求有两个相邻的相同非空白字符。使用
while (<STDIN>)
逐行读取标准输入,若当前行匹配该模式则打印该行。
21、附加题:编写一个程序,打印出任何同时提及了“wilma”和“fred”的输入行。假设输入内容存储在一个文本文件中。
可使用正则表达式和编程语言来实现。以 Python 为例,代码如下:
for line in open('input.txt'):
if 'wilma' in line.lower() and 'fred' in line.lower():
print(line.strip())
上述代码假设输入内容存储在名为
'input.txt'
的文件中,可以根据实际情况修改文件名。
22、创建一个模式,该模式能匹配当前 $what 变量中内容的三个连续副本。也就是说,如果 $what 是 fred,你的模式应匹配 fredfredfred。如果 $what 是 fred|barney,你的模式应匹配 fredfredbarney、barneyfredfred、barneybarneybarney 或其他多种组合。(提示:你应该在模式测试程序的顶部使用类似 my $what = ‘fred|barney’; 的语句来设置 $what。)
可以使用模式
/($what){3}/
来实现。在 Perl 代码中可以这样写:
my $what = 'fred|barney';
if ($_ =~ /($what){3}/) {
print "匹配成功
";
}
这里将
$what
变量用括号括起来形成捕获组,然后用
{3}
表示该捕获组连续出现三次。
23、编写一个程序,对文本文件进行修改复制。在复制文件中,每个字符串 Fred(不区分大小写)应替换为 Larry。(例如,Manfred Mann 应变为 ManLarry Mann。)输入文件名应通过命令行给出(不要询问用户),输出文件名应为对应的以 .out 结尾的文件名。
以下是实现该功能的程序代码:
if (! open $in_fh, '<', $in ) { die "Can't open '$in': $!";}
if (! open $out_fh, '>', $out ) { die "Can't write '$out': $!";}
while (<$in_fh>) {
s/Fred/Larry/gi;
print $out_fh $_;
}
此程序先处理命令行参数获取输入文件名,将其复制到
$out
并把文件扩展名改为
.out
(也可直接在文件名后追加
.out
)。打开输入和输出文件句柄后,开始逐行读取输入文件,使用
s/Fred/Larry/gi
进行不区分大小写的全局替换,将
Fred
替换为
Larry
,然后将替换后的行写入输出文件。
24、编写一个程序,它会不断要求用户猜测一个1到100之间的秘密数字,直到用户猜对为止。程序应使用神奇公式 int(1 + rand 100) 随机选取一个数字。当用户猜错时,程序应回应“Too high”(太高)或“Too low”(太低)。如果用户输入“quit”或“exit”,或者输入空行,程序应退出。当然,如果用户猜对了,程序也应退出。
以下是使用Perl实现该功能的示例代码:
use 5.010;
my $secret = int(1 + rand 100);
while (1) {
print "Please enter a guess from 1 to 100 (or 'quit' to exit): ";
chomp(my $guess = <STDIN>);
if ($guess eq 'quit' || $guess eq 'exit' || $guess eq '') {
last;
}
if ($guess =~ /^d+$/) {
if ($guess > $secret) {
print "Too high
";
} elsif ($guess < $secret) {
print "Too low
";
} else {
print "Correct! You guessed the secret number.
";
last;
}
} else {
print "Invalid input. Please enter a number or 'quit'.
";
}
}
这段代码首先使用
int(1 + rand 100)
生成一个1到100之间的随机数作为秘密数字。然后,程序进入一个无限循环,不断提示用户输入猜测的数字。如果用户输入“quit”、“exit”或空行,程序将退出循环。如果用户输入的是一个有效的数字,程序将比较该数字与秘密数字的大小,并给出相应的提示。如果用户猜对了,程序将输出正确信息并退出循环。如果用户输入的不是有效的数字,程序将提示用户输入无效。