2017-03-31 145 views
5

我有一个数字列表L。还有另一个号码列表M。我需要返回一个列表L”在大号中号发现号Perl6:匹配列表中的元素与另一个列表

编辑:数学,我找Multiset交集。

实施例:

大号 = 3,1,4,1,5,92,6
中号 = 9,7,121,1
L' = 9,1,2,1,

我写了following code

my @some-numbers = 3, 1, 4, 1, 5, 9, 2, 6; 
my @to-match  = 9, 7, 1, 2, 1, 1; 
my @matched; 

my %histogram; 
for @some-numbers -> $n { %histogram{$n}++ }; 

for @to-match -> $n { 
    next if not defined %histogram{$n}; 
    if %histogram{$n} > 0 { 
     push @matched, $n; 
     %histogram{$n}--; 
    } 
}; 

say @matched; 

虽然达到了目的,我想知道是否有这样做的惯用 Perl6方式?

一些背景:我一直在努力学习Perl6和Python在一起,并解决在这两种语言相同的谜题。针对上述问题,Python特别提供了pleasing solution。在我初学的眼睛至少:)

+0

为什么'L''中有两个'1',而不是三个? –

+0

在Perl5中,您可以执行'my%seen = map {$ _ => 1} @to_match;我的@match = grep {存在$见过{$ _}} @ some_numbers' –

+0

对不起,在构思问题时不精确。我现在意识到我正在寻找的是[Multiset](https://en.wikipedia.org/wiki/Multiset)交集。我编辑了问题陈述以反映这一点。谢谢:) – Anant

回答

6

根据您要查找的精确语义,Bag操作可能只是门票:

my \L = 3, 1, 4, 1, 5, 9, 2, 6; 
my \M = 9, 7, 1, 2, 1, 1; 

.put with L.Bag ∩ M.Bag; 

显示:

9 1(2) 2 

这是一个Bag的包含三个字串'9','1''2'其各自的(重复计数)是整数1,21

要获得的Perl 6以从与每个键一个袋产生的列表重复的通过其相关联的值所指示的次数,可使用.kxxv方法:

.kxxv.put with L.Bag ∩ M.Bag; 

显示:

9 1 1 2 

kxxv方法的助记符是k的“关键”,然后xx类似于xx重复操作符,最后是v“值”。如果你仔细想一想,这是有意义的。)

但也许一个包不会。例如,结果中元素的顺序可能很重要 - 您需要9 1 2 1而不是9 1 1 2?如果行李不正确,我会延长这个答案。

+0

如果“9 1 2”是一个可以接受的答案,实际上你并不需要首先强迫Bag,你可以将两个列表交叉:“L(&)M”(使用德克萨斯版本的∩)。该交集默认使用Set语义。 –

+0

手袋对我来说是完美的!从交集返回的元素顺序无关紧要。 – Anant

1

你可以试试这个:

use v6; 

my @some_numbers = 3, 1, 4, 1, 5, 9, 2, 6; 
my @to_match  = 9, 7, 1, 2, 1, 1; 
my %seen = map { $_ => 1 }, @to_match; 
my @matched = grep { %seen{$_}:exists }, @some_numbers; 
say @matched; 

输出

[1 1 9 2] 
+2

有点Perl5ish看.. 你可以使用'@to_match X => 1;'来构建%%散列而不是地图, 或者只是完全放弃%看到的散列并使用'@some_numbers。 grep:{@ to_match.first($ _)};' –

+2

如果第一个列表中有额外的元素,则不能正确工作:'@some_numbers = 3,1,4,1,5,9,2,6,1; @to_match = 9,7,1,2,1' –

6

你可以用塑料袋做:

my $some-numbers = bag 3, 1, 4, 1, 5, 9, 2, 6; 
my $to-match  = bag 9, 7, 1, 2, 1, 1; 
my $matched  = $some-numbers ∩ $to-match; 
say $matched; 

输出:

bag(9, 1(2), 2) 

您可以将袋子变回到.kxxv的阵列中。

my @match-list = $matched.kxxv; 
say @match-list; 

输出:

[9 1 1 2] 

(如果你不关心重复,使用装置来代替塑料袋。)

+1

对于Unicode运算符有问题的人来说,德克萨斯版的'∩'是'(&)' – Christoph

相关问题