2017-02-13 42 views
0

我在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

回答

1

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

0

我已經使用了一個數組來存儲輸出,這是一種更加結構化的方式來處理多個值。請在下面查找我已修改的代碼。

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

0

首先,我們來修復其中$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;