程序打印传递计数为1,失败计数为-1

问题描述:

我在perl中编写了这个脚本,其中我提取了通过次数和失败次数并将其打印为1和-1。 下面是我尝试过的,它工作得很好,但我想知道是否有一种方法可以即兴编码?程序打印传递计数为1,失败计数为-1

my $pc = 10; 
my $fc = 5; 
my $v = ""; 
my $c = 0; 

while ($c < $pc){ 
    if ($c > 0) { 
     $v .= ","; 
    } 
    $c++; 
    $v .= "1"; 
} 
$v .= ","; 
$c=0; 
while ($c < $fc){ 
    if ($c > 0) { 
     $v .= ","; 
    } 
    $c++; 
    $v .= "-1"; 
} 
print $v; 
print "\n"; 

output:1,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1 

欣赏任何想法或建议。

+0

写$ c = 0后,更多的代码;打印一个“,”? –

+0

Jeroen Heier:谢谢,我做了,它照顾了“,”。但是有没有办法我可以进一步提高这个代码呢?特别是与while循环? – anyname

+1

你从哪里获得了为变量使用不可识别的单字符标识符的想法?明智的标识符以及该语言的英文关键字应该产生一个可读的程序。如果你在街上阻止某人,他们将不知道'$ pc'或'$ fc'可能意味着什么,但是每个人都知道'$ pass_count'和'$ fail_count'。 – Borodin

Perl提供了广泛的高级工具,通常我们不需要显式循环。

直接回答这个问题

my $v = join ',', (1) x $pc, (-1) x $fc; 

我们建立使用列表(1)repetition operator (x)的的1名单。由于join中的模式都是其输入列表,因此我们也可以使用它们之间的comma operator来提供-1 s的列表。这个组合元素(扁平)名单,然后由,

当然加入,如果您需要解决那些1 s这个是行不通的动态东西。


这里是另一种方法,它适用于更一般的条件。

+1

my $v = join ',', map { 1 } 1..$pc; 

的一部分,并与-1

$v .= join ',', map { -1 } 1..$fc; 

这部分也可以被制作成如第一示例一条线,如果需要和合适的。

map为输入列表的每个元素运行代码块,并返回结果列表。在块内部,每个元素都在$_ variable中可用,并且代码通常使用它。这就是我们如何以功能(和声明)的方式生成另一个列表的方式。

但是在这个例子中你只需要列表1 s,所以每次从块返回1$pc次。然后,该输出列表变成join的输入,元素加入,。第二行为-1执行$fc次,然后将连接字符串附加到$v

+0

使用[子程序](https://www.tutorialspoint.com/perl/perl_subroutines.htm)如果你想在更多的地方使用这个代码 –

+0

@JeroenHeier这可能是一个很好的建议,对于OP来说,他们的代码。据推测它在某些子程序中。 – zdim

+0

@zdim:谢谢你,这让我的代码看起来更简单。 – anyname

我已经使用了一个数组来存储输出,这是一种更加结构化的方式来处理多个值。请在下面查找我已修改的代码。

my $pc = 10; 
my $fc = 5; 
my @v; 
my $c = 0; 
$c=$pc; 
while ($c){ 
    push @v, "1"; 
    $c--; 
} 
$c=$fc; 
while ($c){ 
    push @v, "-1"; 
    $c--; 
} 
local $, = ','; 
print @v; 
print "\n"; 

注 - 请注意,输出位于数组中,分隔符(,)仅用于格式化输出,并且不在数组中。使用$, = ','我们可以将任何东西设置为输出分隔符。

+0

没有理由使用'local $,=','; print @v; print“\ n”;'而不是'print(join(',',@v),“\ n”);'。 – ikegami

首先,我们来修复其中$pc == 0$fc > 0返回,-1,-1,...而不是-1,-1,...的问题。

my $v = ""; 
my $c = 0; 
for (1..$pc) { 
    $v .= "," if $c++ > 0; 
    $v .= "1"; 
} 
for (1..$fc) { 
    $v .= "," if $c++ > 0; 
    $v .= "-1"; 
} 

其次,让我们使用数组来收集值,并加入内容以避免所有逗号代码。

my @v; 
for (1..$pc) { 
    push @v, "1"; 
} 
for (1..$fc) { 
    push @v, "-1"; 
} 

my $v = join(',', @v); 

这看起来极像是的map[1]的定义!所以,

my @v; 
push @v, map { "1" } 1..$pc; 
push @v, map { "-1" } 1..$fc; 
my $v = join(',', @v); 

或者只是

my $v = join ',', 
    map({ "1" } 1..$pc), 
    map({ "-1" } 1..$fc); 

最后,由于map的身体是不变的,我们可以使用重复操作符。

my $v = join ',', 
    ( "1") x $pc, 
    ("-1") x $fc; 

  1. 这就是说

    my @v; for (LIST) { push @v, f($_) } 
    

    可以写成

    my @v = map { f($_) } LIST;