我有一个包含此文本的文件:
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的内容,我试过但是我没有找到解决方案, 谢谢大家。
答案 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