0

Perlでの私の質問は次のようなものです:

一連の従業員番号と毎日の労働時間を標準入力、1セットの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のループを1回使用すると、次のようになります。

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

どこが間違っているのですか?

4

1 に答える 1

2

このコードスニペットには問題があります。

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 += $_;
}

(もちろん、代わりに2つのループを組み合わせることができます)。

更新:これは、すべての要件を満たすと私が信じる完全に修正されたコードです。

#!/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";
于 2012-10-17T09:52:49.477 に答える