我有2个哈希 - > %a
和%b
。
哈希%a
来自temp.txt
my %a = map{
my $short = substr($_,12);
$count++ => {$short => $_};
} @a;
my %b = map {
$_ => $_;
} @b;
%a = (
'1' => {'We go lunch' => 'We go lunch 9 pm'},
'2' => {'We go break' => 'We go break 8 pm'},
'3' => {'We go lunchy' => 'We go lunchy 8 pm'}
);
%b = (
'We go lunch' => 'We go lunch',
'We go break' => 'We go break',
'We go lunchy' => 'We go lunchy'
);
foreach my $key (keys %a){
foreach my $key2 (keys %{$a{$key}}){
if(exists $b{$key2}){
delete $a{$key}{$key2};
delete $a{$key};
}
}
}
my @another;
foreach my $key ( sort {$a<=>$b} keys %a) {
foreach my $key2 (keys %{$a{$key}}){
$another[$count] = $a{$key}{$key2};
$count++;
}
}
我怎样才能加快这个?我的哈希很奇怪吗?在@another
中输出temp.txt
到25144行单词需要30秒。
是否有必要为%a
制作哈希哈希值?
原因是我希望删除%b{$key}
中的任何%a
值。
我还在学习Perl,如果你们有更好的方法做到这一点,非常感谢,可能使用map和grep?更好的算法?
以前的解决方法
如果你看到每个@b都比每个@a短,但仍然在@a中。我曾尝试使用
foreach (@b) {
my $source = $_;
@another = grep !(/$source/i), @a;}
但仍然不起作用。我很困惑,因此在%a中出现了哈希哈希值,并从@b中创建了哈希%b,以便在@a中删除@b的每个实例值。这是奇怪的哈希。洛尔
答案 0 :(得分:2)
这里有一些未知数 - 例如%b
是如何构建的。
否则,请注意几点:
您应该使用另一个数组而不是%a
:
my @c = map{
{ "".substr($_,12) => $_}
} @a;
如果您已定义%b
,则可以通过以下方式进一步优化:
my @another = grep !exists $b{ substr($_,12) }, @a;
希望这有帮助
另外,不要忘记在程序开头始终 use strict;
和use warnings;
。
<强>说明:强>
您的代码将所有内容放在%a
中,遍历它并消除不应存在的内容。
我认为你可以简单地grep
并且只在数组中保留所需的结果。
优化代码应该成为:
use strict;
use warning;
my %b = (
'We go lunch' => 'We go lunch',
'We go break' => 'We go break',
'We go lunch' => 'We go lunch'
);
#add code that initially fills @a
my @another = grep { !exists $b{ substr($_,12) } } @a;
答案 1 :(得分:1)
看来你很困惑。首先, 对我们来说,最大的问题是你没有在所有这些中解释你的目标。 您希望最终得到的数组 我会通过从数组 该程序演示。我已将数组 之后,读取文件,检查每行与正则表达式是一个简单的问题,并将那些不匹配的行推到 请注意,就目前而言,程序从 <强>输出强> substr $_, 12
返回字符串中第12个之后的所有字符,因此不会创建您所说的数据结构。其次,您使用散列哈希%a
作为数组,因为键是序列中没有间隙的整数,并且您存储的值是一个简单的字符串对。 / p>
@another
包含来自temp.txt
的所有不以@b
中的任何字符串开头的行。那是对的吗?@b
构建正则表达式,并在读取文件时检查文件中的每一行来实现。@b
重命名为@exclude
,因为前者是变量的可怕的名称。正则表达式是通过在数组的每个元素前面加^
来构建的,以将正则表达式锚定在字符串的开头,并附加\b
来强制单词边界(例如,{{{ 1}}与lunch
不匹配。然后使用lunchy
交替运算符将所有元素连接在一起,从而生成一个匹配字符串的正则表达式,该字符串以 |
中任何行开头。@exclude
。@another
文件句柄读取,以便我可以在源中包含一些测试数据。您应该通过取消注释DATA
行并删除第open
行来更改它。my $fh = *DATA
use strict;
use warnings;
#open my $fh, '<', 'temp.txt' or die $!;
my $fh = *DATA;
my @exclude = (
'We go lunch',
'We go lunchy',
'We go break',
);
my $exclude_re = join '|', map "^$_\\b", @exclude;
my @another;
while (my $line = <$fh>) {
chomp $line;
push @another, $line unless $line =~ $exclude_re;
}
print "$_\n" for @another;
__DATA__
We go breakfast 6 am
We go lunch 9 pm
We go break 8 pm
We go lunchy 8 pm
We go supper 7 pm