【问题标题】:Perl Hash ScriptPerl 哈希脚本
【发布时间】:2012-10-07 08:32:38
【问题描述】:

我在 Perl 中的问题是这样的:

从标准输入中读取一系列员工编号和每日工作时间,一组 perl 行。员工编号和工作小时数应以空格分隔。使用哈希计算总工作小时数和每个工作周期的平均小时数。按排序的员工编号、工作时段数、总工作小时数和每个工作时段的平均小时数打印报告。假设一些员工是兼职,并且工作的天数或小时数与普通员工不同。

我的脚本是:

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

my @series = qw(41234 9 67845 8 32543 10 84395 7 57543 9 23545 11);
my $workper = 3;
my %empwork;

while (my $series = shift @series) {

    my $nums = shift @series;
    $empwork{$series} += $nums;
}

my $tot;
foreach (sort keys %empwork) {

    $tot += $empwork{$_};
}

my $avg = $tot/$workper;
print "Sorted Employee Numbers:\n";
foreach my $empnum(sort keys %empwork) {

    print "$empnum\n";
}
print "The number of work periods is $workper\n";
print "Total number of hours is $tot\n";
print "Average number of hours per work period is $avg\n";

我的输出是:

Sorted Employee Numbers:
23545
32543
41234
57543
67845
84395
The number of work periods is 3
Total number of hours is 54
Average number of hours per work period is 18

谁能告诉我我是否在脚本中做错了什么。如果是,请帮忙。提前致谢。

如果我像这样使用 %empwork 循环:

foreach my $empnum(sort keys %empwork) {

    $tot += $empwork{$_};
    print "$empnum\n";
}

然后我会得到如下输出:

Sorted Employee Numbers:
23545
32543
41234
57543
67845
84395
The number of work periods is 3
Total number of hours is 0
Average number of hours per work period is 0
Use of uninitialized value in hash element at /tmp/135043087931085.pl line 16.
Use of uninitialized value in addition (+) at /tmp/135043087931085.pl line 16.
Use of uninitialized value in hash element at /tmp/135043087931085.pl line 16.
Use of uninitialized value in addition (+) at /tmp/135043087931085.pl line 16.
Use of uninitialized value in hash element at /tmp/135043087931085.pl line 16.
Use of uninitialized value in addition (+) at /tmp/135043087931085.pl line 16.
Use of uninitialized value in hash element at /tmp/135043087931085.pl line 16.
Use of uninitialized value in addition (+) at /tmp/135043087931085.pl line 16.
Use of uninitialized value in hash element at /tmp/135043087931085.pl line 16.
Use of uninitialized value in addition (+) at /tmp/135043087931085.pl line 16.
Use of uninitialized value in hash element at /tmp/135043087931085.pl line 16.
Use of uninitialized value in addition (+) at /tmp/135043087931085.pl line 16.

我尝试了以下程序。但它不起作用。

#!/usr/bin/perl
use strict;
use warnings;
my @series = qw(41234 9 67845 8 32543 10 84395 7 57543 9 23545 11 23545 1 23545 2 23545 6);
my $total_periods = 0;
my $total_hours = 0;
my %empwork;
while (my $series = shift @series) 
{
 my $nums = shift @series;
 $empwork{$series} += $nums;
}
print "Sorted Employee Numbers:\n";
foreach my $empnum(sort keys %empwork) 
{
 my $periods=0;
 $periods++;
 my $hours = 0;
 $hours += $empwork{$empnum}; 
 my $avg = $hours/$periods;
 $total_periods += $periods;
 $total_hours += $hours;
 print "$empnum\n$periods periods\n$hours hours\n$avg average\n\n";
}
my $grand_avg = $total_hours/$total_periods;
print "The number of work periods is $total_periods\n";
print "Total number of hours is $total_hours\n";
print "Average number of hours per work period is $grand_avg\n";

我哪里错了?

【问题讨论】:

  • use strictuse warnings 始终是可取的。您也不需要遍历%empwork 两次。打印并一次性计算总数。
  • 周期定义为$workper=3;
  • 我的代码对这里提出的问题完美吗?这就是我对你们所有人的疑问。
  • 我注意到您不接受我的回答。您是否还有其他未涵盖的问题?
  • 是的,先生。因为根据我需要帮助的问题,我觉得脚本仍然不完美。

标签: perl


【解决方案1】:

这段sn-p的代码有问题:

foreach my $empnum(sort keys %empwork) {

    $tot += $empwork{$_};
    print "$empnum\n";
}

您使用$empnum 作为循环迭代器变量,但随后引用$empwork{$_}。这就是你得到错误的原因。只需将其替换为 $empwork{$empnum} 即可。

上面显示的其余代码都可以正常工作。不过,有几点建议:

您的源数组中是否会有重复的员工编号?示例数据未显示任何内容。如果没有重复,您可以简单地执行此操作来填充哈希,并取消您的 while 循环:

%empwork = @series;

另外,在这部分:

foreach (sort keys %empwork) {

    $tot += $empwork{$_};
}

当您不执行与顺序相关的操作时,没有理由对键进行排序。它只会让解释器做不必要的工作。在这种情况下,您甚至不需要密钥;您只对将这些值相加感兴趣。所以,你可以这样做,效率更高:

foreach (values %empwork)
{
    $tot += $_;
}

(当然,您可以将两个循环组合起来)。

更新:这是完整的更正代码,我相信它将满足您的所有要求。

#!/usr/bin/perl
use strict;
use warnings;
use List::Util qw/sum/;

my @series = qw(41234 9 67845 8 32543 10 84395 7 57543 9 23545 11 23545 1 23545 2 23545 7);
my $total_periods = 0;
my $total_hours = 0;
my %empwork;
while (my $series = shift @series) {
    #For each employee, save a list of the number of times they worked
    push @{$empwork{$series}}, shift @series;
}

print "Sorted Employee Numbers:\n";
foreach my $empnum(sort keys %empwork) {
    my $periods = @{ $empwork{$empnum} };
    my $hours   = sum(@{ $empwork{$empnum} });
    my $avg = $hours/$periods;
    $total_periods += $periods;
    $total_hours += $hours;
    print "$empnum\n$periods periods\n$hours hours\n$avg average\n\n";
}

my $grand_avg = $total_hours/$total_periods;

print "The number of work periods is $total_periods\n";
print "Total number of hours is $total_hours\n";
print "Average number of hours per work period is $grand_avg\n";

【讨论】:

  • 先生。如果我不想使用'使用 List::Util qw/sum/;'和'我的 $hours = sum(@{ $empwork{$empnum} });'我只想使用简单的 Perl 编程使用哈希来解决它,我该如何解决它?
  • @user1613245, List::Util 是核心 Perl 发行版的一部分,因此没有充分的理由不使用它。但是,如果您不想这样做,您可以自己轻松地对数组求和:my $hours = 0;$hours += $_ foreach (@{ $empwork{$empnum} });
  • 是的。我得到了所需的脚本和输出。非常感谢先生。
  • 先生,最后一个问题。而不是这一行 -> my $periods = @{$empwork{$empnum}}; ,有没有其他方法来计算周期而不像你展示的那样直接使用@args 来计算小时数?
  • @user1613245,请解释为什么你不想这样做。员工的期间数只是该行获取的数组中元素的数量。
猜你喜欢
  • 2015-10-25
  • 2013-11-17
  • 2013-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-23
  • 2013-12-20
相关资源
最近更新 更多