我有2个标量如下:
$a = '100 105 010';
$b = '010 105 100';
如果两者具有相同的值集,我如何比较?订单没关系。 一种方法是按升序排列并进行比较,有更好的方法吗?
答案 0 :(得分:0)
没有模块,你可以使用哈希:
#!/usr/bin/perl
use warnings;
use strict;
my $x = '100 105 010 2';
my $y = '010 105 100 100 1';
my (%hx, %hy);
$hx{$_}++ for split ' ', $x;
$hy{$_}++ for split ' ', $y;
for my $k (keys %hx) {
if (! exists $hy{$k}) {
print "$k missing in y\n";
} elsif ($hy{$k} != $hx{$k}) {
print "$k has different number of occurences\n";
}
delete $hy{$k};
}
print "$_ missing in x\n" for keys %hy;
$a
和$b
是sort
中使用的特殊变量,因此我将其重命名为$x
和$y
。
split将字符串转换为列表。每个哈希计算成员在列表中出现的次数。
另见Perl FAQ 4。
答案 1 :(得分:0)
您可以将每个字符串拆分为一个数组,然后对数组进行排序和比较。手工:
use warnings;
use strict;
my $x = '100 105 1 010';
my $y = '010 105 100 2';
my @xs = sort { $a <=> $b } split ' ', $x;
my @ys = sort { $a <=> $b } split ' ', $y;
if (@xs != @ys) {
print "Differ in number of elements.\n";
}
else {
for (0..$#xs) {
print "Differ: $xs[$_] vs $ys[$_]\n" if $xs[$_] != $ys[$_];
}
}
# For boolean comparison put it in a sub
print arr_num_eq(\@xs, \@ys), "\n";
sub arr_num_eq {
my ($ra, $rb) = @_;
return 0 if @$ra != @$rb;
$ra->[$_] != $rb->[$_] && return 0 for 0..$#$ra;
return 1;
}
排序也可以移动到sub,然后接受字符串。它的方式也可用于比较现有的数组。请添加参数检查。
有许多模块具有此功能。来自perm的Array::Compare隐藏了上面的排序,但内部将排序的数组连接成字符串,因此我们从字符串开始重复了这里的工作。 List::AllUtils当然也提供了很长的实用程序列表。
例如,请参阅this post,了解一些方法(不是智能匹配 ~~
),如果效率问题,请参阅基准测试。
使用Array::Compare中提到的实施构思,每个评论ysth
sub str_num_eq {
return join(' ', sort { $a <=> $b } split / /, $_[0])
eq join(' ', sort { $a <=> $b } split / /, $_[1])
}
最合适的方法取决于它的用途和使用方法。它只是一个布尔比较,或者如果发现它们不同会更多吗?它是如何在您的程序流程中出现的?什么是典型的字符串大小,它的运行频率是多少?字符串通常是相同还是不同,它们通常会有很大差异吗?等
答案 2 :(得分:0)
其他尝试使用模式匹配,
这不是直截了当但它会起作用。
按标量值的任何人构造模式。然后按构造的模式检查另一个字符串。
my $a = '100 100 105';
my $b = '100 105 100';
my @b_ary = split(" ",$b);
my $regex = join'\b|\b', @b_ary;
my $word_length = @b_ary * 2 - 1; #Count the number of words and space.
my $rgx = qr"^(?:\b$regex\b|\s){$word_length}$"; #`{n}` match word exact n times
if($a=~m/$rgx/)
{
print "same values\n";
}
else
{
print "Not a same values\n";
}
答案 3 :(得分:0)
上面已经公布了答案。这是为了防止您想要删除空格并比较每个数字。
$x = '100 105 010';
$y = '010 105 100';
join("",sort split "",join("",split " ",$x)) eq join("",sort split "",join("",split " ",$y));