使用相应的键打印Perl中哈希值的最小值和最大值

时间:2018-01-25 14:57:02

标签: arrays perl sorting hash

我是Perl的新手(我也会说一般的编程),我正在尝试使用perl脚本解决一个简单的问题。我不应该使用任何模块,我认为他们不会接受它,因为我必须先学习如何做事。

我被要求创建一个html输入表单,用于输入学生姓名和标记,并将它们传递给我的perl脚本并计算每个学生的GPA,直到现在一切正常。

然后我应该将这些信息保存在哈希中,并获得获得最高GPA的学生姓名,然后获得最低的学生姓名,但没有任何工作。

首先,我将每个GPA定义在任何函数之外,以便在每个子例程中都可读,然后我尝试将每个学生名称分配给他的GPA,但我不确定这是否正确。

my $cgi = CGI -> new();

my @name = $cgi->param('name');

my $gpa_one;
my $gpa_two;
my $gpa_three;
my $gpa_four;
my $gpa_five;
my $gpa_six;
my $gpa_seven;
my $gpa_eight;
my $gpa_nine;
my $gpa_ten;

my %stud_gpa = (
$name[0] => $gpa_one,
$name[1] => $gpa_two,
$name[2] => $gpa_three,
$name[3] => $gpa_four,
$name[4] => $gpa_five,
$name[5] => $gpa_six,
$name[6] => $gpa_seven,
$name[7] => $gpa_eight,
$name[8] => $gpa_nine,
$name[9] => $gpa_ten,
);

每个GPA都是子程序的结果。

我一直在尝试以多种方式对GPA进行排序(对哈希进行排序,只是尝试将它们分配给一个简单的数组并对数组进行排序)但是我没办法让它工作。

这是我尝试用哈希做的子程序:

sub gpa_hash{

    my @gpavalues = sort { $stud_gpa{$a} <=> $stud_gpa{$b} } keys %stud_gpa;
    my $highest = $gpavalues[-1];
    my $smallest = $gpavalues[0];
    print "the max GPA is $highest of the student $stud_gpa{$gpavalues[-1]}<br>";
    print "the min GPA is $smallest of the student $stud_gpa{$gpavalues[0]}<br>";

}

但是我对输出有些问题,因为这是我得到的:

the max GPA is of the student 
the min GPA is of the student 

然后我尝试了一个数组,看看它是否可能更容易理解:

my @tot_gpa = (
           \$gpa_one,
           \$gpa_two,
           \$gpa_three,
           \$gpa_four,
           \$gpa_five,
           \$gpa_six,
           \$gpa_seven,
           \$gpa_eight,
           \$gpa_nine,
           \$gpa_ten
);

sub gpa{
    my $max = (sort { $a <=> $b } @tot_gpa)[-1];
    my $min = (sort { $a <=> $b } @tot_gpa)[0];
    print "this is the smallest GPA: $min<br>";
    print "this is the highest GPA: $max<br>";
}

但这就是我所得到的:

this is the smallest GPA: SCALAR(0x8bcab0)
this is the highest GPA: SCALAR(0x8bcbd0)

我确信我在将变量分配给数组时首先做错了,因为如果我只是打印数组本身就会给我这个输出:

SCALAR(0x8bcab0)
SCALAR(0x8bcad0)
SCALAR(0x8bcaf0)
SCALAR(0x8bcb10)
SCALAR(0x8bcb30)
SCALAR(0x8bcb50)
SCALAR(0x8bcb70)
SCALAR(0x8bcb90)
SCALAR(0x8bcbb0)
SCALAR(0x8bcbd0)

如果我只是单独打印GPA变量,我会得到正确的相应数字,例如print "$gpa_one<br>";给我(例如)2.1。有人可以帮助我理解如何解决它吗?我疯了......

谢谢!

2 个答案:

答案 0 :(得分:2)

sort返回其输入列表已排序,因此在您的子

sub gpa_hash {

    my @gpavalues = sort { $stud_gpa{$a} <=> $stud_gpa{$b} } keys %stud_gpa;
    my $highest = $gpavalues[-1];
    my $smallest = $gpavalues[0];
    ...
}

@gpavalues 不是值,而是键,按块中的条件排序。

因此您可以通过

检索值
my $largest  = $stud_gpa{$gpavalues[-1]};
my $smallest = $stud_gpa{$gpavalues[0]};

my ($largest, $smallest) = @stud_gpa{ @gpavalues[-1,0] };

使用数组和哈希slices

一些一般性评论。

看起来您将变量设为全局变量,以便子程序可以看到它们。这似乎可行,但随着程序变得更复杂,它肯定会导致麻烦。你应该总是编写你的subs来通过参数从调用代码中获取他们需要的数据。

我不知道所有$gpa_N的手动列表的目的,但它们应该是多值数据类型或变量的明确(未命名)元素,如数组。鉴于您将它们分配给哈希值,您可以在获得这些值时正确地执行此操作。

答案 1 :(得分:-1)

SCALAR(0x8bcbd0)

表示您正在标量上打印参考

为了打印标量而不是其地址

,您将不得不参考

这将通过替换

来完成
my $max = (sort { $a <=> $b } @tot_gpa)[-1];

通过

my $max = ${(sort { int($$a) <=> int($$b) } @tot_gpa)[-1]};

$在开头$a之前$b$a无法参考你的标量。 仅使用$bint,您可以对地址进行排序,而不是值

my ($gpa_one, $gpa_two, $gpa_three, $gpa_four) = (12.5,15.8,1,2.5); my @tot_gpa = ( $gpa_one, $gpa_two, $gpa_three, $gpa_four ); my $max = (sort { $a <=> $b } @tot_gpa)[-1]; print $max; 强制int上下文来比较数字而不是字符串

你也可以用变量而不是引用填充数组,做类似

的事情
15.8

打印use strict; use warnings; my ($gpa_one, $gpa_two, $gpa_three, $gpa_four) = (12.5,15.8,1,2.5); my %stud_gpa = ( 'a' => $gpa_one, 'b' => $gpa_two, 'c' => $gpa_three, 'd' => $gpa_four, ); sub gpa_hash{ my @gpavalues = sort { $stud_gpa{$a} <=> $stud_gpa{$b} } keys %stud_gpa; my $highest = $gpavalues[-1]; my $smallest = $gpavalues[0]; print "the max GPA is $highest of the student $stud_gpa{$gpavalues[-1]}<br>"; print "the min GPA is $smallest of the student $stud_gpa{$gpavalues[0]}<br>"; } gpa_hash();

现在使用您的哈希我尝试过:

the max GPA is b of the student 15.8<br>the min GPA is c of the student 1

打印$highest

因此名称和gpa会被切换,因为$smallestkeys %stud_gpa包含了您在$gpa

排序时的学生姓名

我无法重现您的问题

它产生你所描述的内容的方式是你的gpa_hash是引用。 如您所述声明您的哈希并修改您的sub gpa_hash{ my @gpavalues = sort { ${$stud_gpa{$a}} <=> ${$stud_gpa{$b}} } keys %stud_gpa; my $highest = $gpavalues[-1]; my $smallest = $gpavalues[0]; print "the max GPA is ${$stud_gpa{$highest}} of the student $highest<br>"; print "the min GPA is ${$stud_gpa{$smallest}} of the student $smallest <br>"; } ,如下所示,这应该有效

vertical-align: top