2013-02-22 34 views
0

文件1具有範圍3-9,2-6等垂直索引的Perl

3 9 
2 6 
12 20 

文件2具有值:列1表示的範圍內,第2列具有值。

1 4 
2 4 
3 5 
4 4 
5 4 
6 1 
7 1 
8 1 
9 4 

我想計算file1中範圍的值(file2,column2)的總和)。例如:如果範圍是3-9,那麼值的總和將是5 + 4 + 4 + 1 + 1 + 1 + 4 = 20

我曾嘗試是:

open (FILE1,"file1.txt"); 
open (FILE2,"file2.txt"); 

@file1 = <FILE1>; 
@file2 = <FILE2>; 

foreach (@file1) 
    { 
     @split_file2 = split("\\s",$_); //splitting the file by space 


foreach (@file2) 
    { 
     @split_file2 = split("\\s",$_); //splitting the file by space 


if (@split_file1[0] == @split_file2[0]) //if column0 of file1 matches with column0 of file2 
    { 
     $x += @split_file2[1]; //sum the column1 of file2 

     if (@split_file2[0] == @split_file1[0]) //until column1 of file1 = column0 of file2. 

      { 
      last; 
      } 
    } 
}} 
+1

該代碼疼一下。 – melpomene 2013-02-22 10:25:34

+0

:p我很着急。 – Geeky 2013-02-22 10:26:07

+2

在嘗試編寫程序之前,您仍然應該學習基本的Perl。 – melpomene 2013-02-22 10:27:22

回答

0

另一種解決方案:

#!/usr/bin/perl 

use strict; 
use warnings; 

my $f1 = shift; 
my $f2 = shift; 
open FH1, "<", $f1 or die "$!\n"; 
open FH2, "<", $f2 or die "$!\n"; 

my %data; 

while (<FH1>) { 
    $data{$1} = $2 if ($_ =~ m/^(\d+)\s+(\d+)$/); 
} 

while (<FH2>) { 
    if ($_ =~ m/^(\d+)\s+(\d+)$/) { 
     my $sum; 
     for ($1..$2) { 
      $sum += $data{$_} if defined($data{$_}); 
     } 
     print "sum for $1-$2: $sum\n" if defined($sum); 
    } 
} 

close FH1; 
close FH2; 

電話:script.pl values.txt ranges.txt

+0

@ dan1111感謝您的意見,我相應地更改了我的答案。但是,exists並不檢查是否定義了現有密鑰的哈希值。爲什麼_通常首選呢? – speakr 2013-02-22 20:30:18

+0

我想這一點很挑剔。你對兩者的區別是對的。在這種情況下,我認爲它檢查了密鑰的存在,因爲沒有定義值的密鑰顯然不能存在。 – 2013-02-23 10:09:06

3
  • 始終使用use strict; use warnings;
  • split /\s/比較容易閱讀。 split ' '是你真正想要的。
  • 請勿使用全局變量(例如文件句柄)。
  • 如果僅通過添加or die $!,檢查open是否成功很有用。
  • 使用有意義的名稱,而不是file1file2

use strict; 
use warnings; 
use feature qw(say); 

use List::Util qw(sum); 

my $file1 = 'file1.txt'; 
my $file2 = 'file2.txt'; 

my @file2; 
{  
    open(my $fh, '<', $file2) 
     or die "Can't open $file2: $!\n"; 
    while (<$fh>) { 
     my ($k, $v) = split; 
     $file2[$k] = $v; 
    } 
} 

{  
    open(my $fh, '<', $file1) 
     or die "Can't open $file1: $!\n"; 
    while (<$fh>) { 
     my ($start, $end) = split; 
     say sum grep defined, @file2[$start .. $end]; 
    } 
} 
+0

謝謝老兄。真棒。 – Geeky 2013-02-22 10:55:35

+0

'split//'很少是任何人*想要的。最有可能的是'split'''或者只是'split' – Borodin 2013-02-22 11:01:18

+0

'說sum @ file2 [$ start .. $ end];'如果每個元素都保證存在,就足夠了。 – ikegami 2013-02-22 11:02:45