代码之家  ›  专栏  ›  技术社区  ›  rodee

比较字符串中包含的两组数字

  •  0
  • rodee  · 技术社区  · 8 年前

    我有两个标量,如下所示:

    $a = '100 105 010';
    $b = '010 105 100';
    

    如果两者具有相同的值集,如何进行比较?秩序无关紧要。

    4 回复  |  直到 5 年前
        1
  •  0
  •   zdim    5 年前

    您可以将每个字符串拆分为一个数组,并对数组进行排序和比较。手动操作:

    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;
    }
    

    有许多模块具有此功能。这个 perm 从…起 Array::Compare 隐藏上面的排序,但在内部将排序的数组连接到字符串中,从而重复了从字符串开始的工作。这个 List::AllUtils 当然,它还提供了一长串实用程序。

    看见 this post 例如,对于一些方法(只是不是 智能匹配 ~~ )对于基准,如果效率是一个问题。

    使用上述实施理念 数组::比较 ,每个评论由 ysth

    sub str_num_eq {
        return join(' ', sort { $a <=> $b } split / /, $_[0]) 
            eq join(' ', sort { $a <=> $b } split / /, $_[1])
    }
    

    最合适的方法取决于它的用途和使用方式。这只是一个布尔比较,或者如果发现它们不同,还会做更多的比较吗?它是如何在你的程序流程中出现的?字符串的典型大小是什么,多长时间运行一次?字符串通常是相同的还是不同的,它们通常差别很大还是很小?等

        2
  •  0
  •   choroba    8 年前

    如果没有模块,您可以使用哈希:

    #!/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 .

        3
  •  0
  •   mkHun    8 年前

    尝试其他模式匹配,

    这不是一个直截了当的方法,但它会奏效的。

    由标量值中的任何一个构造模式。然后通过构造的模式检查另一个字符串。

    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";
    }
    
        4
  •  0
  •   s.patra    8 年前

    答案已经贴在上面了。这只是为了防止您想删除空白并比较每个数字。

    $x = '100 105 010';
    $y = '010 105 100';
    join("",sort split "",join("",split " ",$x)) eq join("",sort split "",join("",split " ",$y));