2011-04-06 264 views
0

順便說一句,我是Perl新手。我有一個Perl腳本,需要計算一個字符串出現在文件中的次數。腳本從文件本身獲取單詞。計數在文件perl中重複的字符串次數

我需要它抓住文件中的第一個單詞,然後搜索文件的其餘部分,看看它是否在其他地方重複。如果重複,我需要它返回重複的次數。如果沒有重複,它可以返回0.我需要它然後獲取文件中的下一個單詞並再次檢查。

我會抓住文件中的第一個單詞,搜索文件重複該單詞,從文件中抓取第二個單詞 ,搜索文件重複該單詞,從文件中抓取第三個單詞,搜索重複這個詞的文件。

到目前爲止,我有一個while循環抓住了我需要的每個單詞,但我不知道如何在不重置當前行的位置的情況下重新搜索它。那麼,我該如何做到這一點?任何想法或建議非常感謝!提前致謝!

while (<theFile>) { 
    my $line1 = $_; 
    my $startHere = rindex($line1, ","); 
    my $theName = substr($line1, $startHere + 1, length($line1) - $startHere); 
    #print "the name: ".$theName."\n"; 
} 
+0

難道僅僅是第一個2個字的文件中,你檢查,或做你需要的計數整個文件中的所有重複單詞? – geoffspear 2011-04-06 18:18:55

+0

我將抓取文件中的第一個單詞,搜索文件重複該單詞,從文件中抓取第二個單詞,搜索文件重複該單詞,從文件中抓取第三個單詞,在文件中搜索重複的那個詞...... – prolink007 2011-04-06 18:22:31

回答

4

使用散列表;

my %wordcount =(); 

while(my $line = <theFile>) 
{ 
    chomp($line); 
    my @words = split(' ', $line); 
    foreach my $word(@words) 
    { 
     $wordCount{$word} += 1; 
    } 
} 

# output 
foreach my $key(keys %wordCount) 
{ 
    print "Word: $key Repeat_Count: " . ($wordCount{$key} - 1) . "\n"; 
} 

$wordCount{$key} - 1在輸出帳戶中第一次看到一個單詞;只有在該文件中只會發現一次的詞將有一個計數0

除非這實際上是家庭作業和/或您必須在您描述的特定莊園中實現結果,否則這將會變得更加高效。

編輯:從下面的評論:

每個字我尋找的不是「第一個字」這是就行了一定的單詞。基本上我有一個csv文件,我跳到第三個值並搜索它的重複。

我仍然會使用這種方法。什麼,你會想要做的是:

  • 分上,因爲這,是一個CSV文件
  • 每行數組中拉出第3個字和存儲您有興趣在自己的哈希表的話
  • 最後,迭代通過「搜索詞」哈希表,並從單詞計數表

於是拔出計數:

my @words = split(',', $line); 
$searchTable{@words[2]} = 1; 

... 

foreach my $key(keys %searchTable) 
{ 
    print "Word: $key Repeat_Count: " . ($wordCount{$key} - 1) . "\n"; 
} 

你必須根據你在第三欄中重複計算的單詞的規則進行調整。您可以在循環插入到wordCount散列之前將它們從@words中刪除。

+0

+1只要所有單詞之間用空格分隔,這都會起作用。也可以拆分/ \ W +/ – Horus 2011-04-06 18:33:46

+0

那麼,即將做的是修改這一點。我將把我想要搜索的所有單詞放入數組中。然後只需搜索文件重複這些單詞。 – prolink007 2011-04-06 18:37:04

+0

@ prolink007 - 呃,呃?你會在數組中放入什麼? – 2011-04-06 18:39:25

1
my $word = <theFile> 
chomp($word); #`assuming word is by itself. 
my $wordcount = 0; 
foreach my $line (<theFile>) { 
    $line =~ s/$word/$wordcount++/eg; 
} 
print $wordcount."\n"; 

查找正則表達式標誌 'E',瞭解更多這是什麼一樣。我沒有測試代碼,但像這樣的東西應該工作。爲了澄清一下,'e'標誌在替換之前將正則表達式的第二部分(替換)評估爲代碼,但不止於此,因此使用該標誌,您應該可以使其工作。

現在,我明白你在問什麼,上述解決方案將無法正常工作。你可以做的是使用sysread將整個文件讀入緩衝區,然後運行同一個替換,但是你必須手動關閉第一個單詞,或者你可以在事實之後遞減。這是因爲sysread執行文件句柄和普通文件句柄的處理方式不同,所以試試這個:

my $word = <theFile> 
chomp($word); #`assuming word is by itself. 
my $wordcount = 0; 
my $srline = ''; 
#some arbitrary very long length, longer than file 
#Looping also possible. 
sysread(theFile,$srline,10000000) 
$srline =~ s/$word/$wordcount++/eg; 
$wordcount--; # I think that the first word will still be in here, causing issues, you should test. 
print $wordcount."\n"; 

。現在,因爲我讀您的評論迴應你的問題,我不認爲你目前的算法是最優的,並且您可能需要一個散列來存儲文件中所有單詞的計數。這可能是最好的使用類似如下的東西:

my %counts =(); 
foreach my $line (<theFile>) { 
    $line =~ s/(\w+)/$counts{$1}++/eg; 
} 
# now %counts contains key-value pair words for everything in the file. 
+0

會在通過while循環時弄亂文件的位置嗎?我試圖避免這種情況,因爲我想如果我以後再打,它會增加行數,當我去調用下一個單詞時,我正在尋找它,它已經增加了超過我需要的次數。我會測試並看看會發生什麼。謝謝 – prolink007 2011-04-06 18:21:27

+0

你是對的,在這種情況下,我的工作將不起作用。我將編輯另一個可能的解決方案。 – Horus 2011-04-06 18:23:23

+0

是的,布賴恩羅奇有一個非常好的主意,我認爲會很好。謝謝你的幫助! Upvoted你的,但我想我會接受他的。 – prolink007 2011-04-06 18:34:35

1

要查找目前你可以做一些事情,如文件中的所有單詞計數:

#!/usr/bin/perl 
use strict; 
use warnings; 

my %count_of; 
while (my $line = <>) { #read from file or STDIN 
    foreach my $word (split /\s+/, $line) { 
    $count_of{$word}++; 
    } 
} 
print "All words and their counts: \n"; 
for my $word (sort keys %count_of) { 
    print "'$word': $count_of{$word}\n"; 
} 
__END__ 
相關問題