比较文件中的所有行

时间:2016-09-02 08:50:22

标签: perl

我有一个包含此文本的文件:

perl java python php scala
java pascal perl ruby ada 
ASP awk php java perl
C# ada python java scala

我想比较每两行并显示共享单词的数量,我写了一个程序,显示第一行和其他行之间共享的单词数,第一行和第二行包含2(perl,java常用词,第一和第三有3个单词,第一和第四有3个单词。 但我想比较第二行与第一行,第三行和第四行,第三行相同,依此类推。 这是我的代码:

open(F,"/home/Bureau/test2/terms.txt")||die " Pb pour ouvrir";
my $firstLine = <F>;

my @a =split(/ /, $firstLine);
while (<F>) {

my @b = split(/ /,$_ );

my @intersection =
    grep { defined }
        @{ { map { lc ,=> $_ } @a } }
           { map { lc } @b };
print $#intersection."\n";
} 

我认为问题是如何用下一行改变@a的内容,我试过但是我没有找到解决方案, 谢谢大家。

3 个答案:

答案 0 :(得分:3)

  

但我想将第二行与第一行,第三行和第二行进行比较   第四,第三行相同

我的建议是创建一个包含行号和其中的单词的正确数据结构。这样可以很容易地将任何一行与另一行进行比较。例如,见下文:

case "HTTP": {
    HttpProxyHost httpProxy = new HttpProxyHost();
    processRow(row, httpProxy, httpProxies);
    proxy = httpProxy;
    break;
}

这提供了以下结构,您可以轻松地获取所需数据:

use warnings;
use strict;    
use Data::Dumper;

my %lines;

while(<DATA>) {
    chomp;
    my @words_in_line = split /\s/, $_;
    $lines{$.} = \@words_in_line;
}
print Dumper \%lines;

__DATA__
perl java python php scala
java pascal perl ruby ada 
ASP awk php java perl
C# ada python java scala

示例:比较第一行与第三行

$VAR1 = {
          '4' => [
                   'C#',
                   'ada',
                   'python',
                   'java',
                   'scala'
                 ],
          '3' => [
                   'ASP',
                   'awk',
                   'php',
                   'java',
                   'perl'
                 ],
          '2' => [
                   'java',
                   'pascal',
                   'perl',
                   'ruby',
                   'ada'
                 ],
          '1' => [
                   'perl',
                   'java',
                   'python',
                   'php',
                   'scala'
                 ]
        };

这对我来说看起来很灵活,而不是在循环中处理所有事情并处理过于严格的前一个/当前/下一行。

答案 1 :(得分:1)

结合Chankey和我的答案,给出了以下解决方案。

首先构建一个哈希数组,它代表每一行(第一个while循环,基于Chankey的答案)。

然后我们用foreach逐步遍历数组的每个元素。然后我们创建一个splice其他元素减去当前&#34; line&#34;我们正在处理最终的@others。然后我们比较&#34;现在的行&#34; $lines[$count]使用grep@others内的其他行进行map哈希@others $_map的每个元素都在grep内设置%results 1}})。

每个比较的结果都放在一个数组引用(use warnings; use strict; use feature 'say'; use Data::Dumper; my @lines; while(<DATA>) { push @lines, { map { $_ => 1 } split }; } my %results; my $count=0; foreach(@lines) { say 'Comparing Line ' . ($count+1) . ' with other lines'; my @others = @lines; splice @others, $count, 1; # this is the same as my first answer, but doing so for # each line via map() @{ $results{$count+1} } = map { [ grep { exists ${$lines[$count]}{$_} } keys %{ $_ } ] } @others; $count++; } print Dumper(\%results); __DATA__ perl java python php scala java pascal perl ruby ada ASP awk php java perl C# ada python java scala 周围的方括号)中,并且foreach行的所有比较都存储在$VAR1 = { '4' => [ [ 'python', 'java', 'scala' ], [ 'ada', 'java' ], [ 'java' ] ], '1' => [ [ 'perl', 'java' ], [ 'perl', 'php', 'java' ], [ 'python', 'java', 'scala' ] ], '3' => [ [ 'php', 'perl', 'java' ], [ 'perl', 'java' ], [ 'java' ] ], '2' => [ [ 'perl', 'java' ], [ 'perl', 'java' ], [ 'ada', 'java' ] ] }; 内;

map

提供输出

@others

只是打破更复杂的部分:

map正在迭代@others,这是一个哈希数组。 每个元素对应于&#34;其他行&#34;我们正在匹配。

对于$_的每次迭代,我们都会得到 keys %{ $_ } 的每个元素 grep { }。这是我们正在比较的每条线。然后,我们通过以下方式获取该特定数组元素的键(&#34;该行的字词&#34;)

$_

接下来,我们将这些字词传递给exists,然后它会在其中收到$lines[$count](每个字一个)。因此,此时我们正在逐步浏览&#34;另一行&#34;的每个单词,并查看我们当前行 exists ${ $lines[$count] }{$_} 中是否${ $lines[$count] }

$_

我们&#34;现在的行&#34; grep,密钥为map(&#34;其他行&#34;我们正在尝试匹配)。

@others会返回当前行与所比较的行匹配的所有单词,而map()会对$count+1内的所有行执行此操作。

最后,在 @{ $results{$count+1} } = map { ... } 内的每个比较结果将返回一个数组数组,这些数组将使用键gpios存储在结果哈希中(行号与)。

volatile uint32_t* gpios;

答案 2 :(得分:1)

此解决方案构建对应于数组行的哈希数组。然后两个嵌套循环使用grep来计算在任何给定散列和所有后续散列中出现的单词数

use strict;
use warnings 'all';

my @data;

while ( <DATA> ) {
    push @data, { map { $_ => 1 } split };
}

for my $i ( 0 .. $#data-1 ) {

    for my $j ( $i + 1 .. $#data ) {

        my $join = grep { $data[$i]{$_} } keys %{ $data[$j] };

        printf "Line %s has %d word%s in common with line %d\n",
            $i + 1,
            $join,
            $join == 1 ? '' : 's',
            $j + 1;        }
}



__DATA__
perl java python php scala
java pascal perl ruby ada 
ASP awk php java perl
C# ada python java scala

输出

Line 1 has 2 words in common with line 2
Line 1 has 3 words in common with line 3
Line 1 has 3 words in common with line 4
Line 2 has 2 words in common with line 3
Line 2 has 2 words in common with line 4
Line 3 has 1 word in common with line 4