2016-10-01 105 views
1

好吧...所以我想用字典CrunchGrep我也試過用Perl來代替。這個grep命令有什麼問題?

crunch 8 12 1234567890 -d [email protected] | grep -v '\([0-9]\) .*\1.*\1.*\1.*' | grep 41106041 

所以,基本上我要過濾這些數字出現3次

grep 41106041 

只是爲了測試,如果代碼工作的所有密碼..它沒有。

我也嘗試了一些「C風格」因爲我還是一個新手Perl代碼的Perl:

#! /bin/perl 
@lines=<STDIN>; 
$c=0; 
foreach $number(@lines) 
{ 
    $acum=undef; 
    $pos=0; 
    while($pos <= &countdig($number)) 
    { 
     if ($acum=$digit) 
     { 
      $c=$c+1; 
     } 
     else 
     { 
      $c=0; 
     } 
     $acum=$digit; 

    } 
    if ($c=3) 
    { 
     print "$number"." "; 
    } 
    $c=0; 
} 

sub countdig 
{ 
    my($j)=0; 
    chomp(my(@n)[email protected]_); 
    print "first dig $n[$j] \n"; 
    while($_[0][$j]>=0 && $_[0][j]<=9) 
    { 
     $j+=1; 

    } 
    print "j total : $j \n"; 

    $j; 
} 

Countdig應該算的數字,但事情的數量。我可以」 t作爲一個列表訪問一個標量變量..如果你們可以向我解釋如何讓它工作,那將是非常值得讚賞的。

回答

3

grep失敗,因爲在你的模式流浪空間,您正在尋找4個相同數字(一捕獲,加上三個由反向引用)。

$ printf '12345678\n41106041\n87654321\n' | grep -v '\(.\).*\1.*\1' 
12345678 
87654321 

問題是不是一個新手到Perl的,因爲它很容易變成一個C解決方案

// For each line 

char *num = ...; 

int digits[10]; 
for (int i=0; i<10; ++i) { 
    digits[i] = 0; 
} 

const char *p = num; 
int triple = 0; 
for (; *p && *p != '\n'; ++p) { 
    if (++digits[*p - '0'] == 3) { 
     triple = 1; 
     break; 
    } 
} 

if (triple) { 
    ... 
} 

到Perl的解決方案

while (my $num = <>) { 
    chomp($num); 

    my @digits; 
    my $triple; 
    for my $digit (split //, $num) { 
     if (++$digits[$digit] == 3) { 
     $triple = 1; 
     last; 
     } 
    } 

    say $num if $triple; 
} 

當然,一個Perl程序員可能會使用與grep相同的方法。

while (<>) { 
    if (!/(.).*\1.*\1/) { 
     print; 
    } 
} 
+0

在OP的第一個數字後面還有一個空格。 – tripleee

+0

c中的解決方案並不是問題,但無論如何要感謝。我在perl與grep中測試了腳本,看起來perl更有效地處理暴力數據的方式。再次感謝您回答這樣一個愚蠢的問題,這對我有很大的幫助。 –

+0

它是有效的,因爲它不*暴力。它最多可以做'長度($ num)'檢查。正則表達式實際上是強力方法,執行多次檢查 – ikegami

0
echo 41106041 | grep -v '\([0-9]\).*\1.*\1.*