7
votes

Comment puis-je comparer des tableaux à Perl?

J'ai deux tableaux, @A code> et @b code>. Je veux faire un comparateur parmi les éléments des deux tableaux.

my @a = qw"abc def efg ghy klm ghn";
my @b = qw"def ghy jgk lom com klm";


4 commentaires

Parce que votre question n'est pas claire, vous obtenez deux types de réponses: (1) ceux qui recherchent des correspondances par paires, telles que $ A [$ i] eq $ b [$ i] ; et (2) ceux qui recherchent une correspondance, telle que $ A [$ i] eq $ b [$ j] . Quel est ton but?


Dupliquer possible de Stackoverflow.com/Questtions/1609467/...


@Sinan: Cette question que vous avez marquée comme "duplication possible" n'est pas la même que celle-ci. Il s'agit de comparer tous les éléments de deux tableaux, mais celui-ci consiste à trouver un élément commun.


@Kinopiko Si les tableaux diffèrent au moins un élément, ils ne sont pas les mêmes. Si les tableaux sont les mêmes, ils ne diffèrent pas des éléments. La réponse acceptée renvoie 0 si au moins une paire est différent et 1 si aucun n'est.


12 Réponses :


7
votes

Liste :: Comparer

if ( scalar List::Compare->new(\@a, \@b)->get_intersection ) {
    …
}


0 commentaires

10
votes

Tout d'abord, vos 2 tableaux doivent être écrits correctement.

if (@a != @b) {
    $equals = 0;
} else {
    $equals = 1;
    foreach (my $i = 0; $i < @a; $i++) {
        # Ideally, check for undef/value comparison here as well 
        if ($a[$i] != $b[$i]) { # use "ne" if elements are strings, not numbers
                                # Or you can use generic sub comparing 2 values
            $equals = 0;
            last;
        }
    }
}


7 commentaires

Vous utilisez scalaire de manière trop libérale à mon goût.


Les opérateurs de comparaison scalaire imposent un contexte scalaire sur leurs arguments. Donc, @a == @b est identique à celui scalaire (@a) == scalaire (@b) et $ i <@a est identique à i .


C'était pour la démo lisibilité ... Je n'utilise presque jamais scalaire () dans le code de production, pour la raison pour laquelle vous ne l'aimez pas ici. Si vous pensez que cela n'aide pas beaucoup, je peux le modifier


C'est très subjectif. Je pense que le pouliche supplémentaire nuit à la lisibilité (sinon, je voudrais toujours programmer en Java ;-)


Je n'ai pas vérifié que cela fonctionne, mais pourquoi ne serait-il pas @a = qw "ABC def defg ghy klm ghn" travail? Ne serait-il pas simplement analysé comme une liste à l'intérieur du délinator défini par l'utilisateur (' "' dans ce cas?) Il ne doit pas être différent de qw // ou qw || ou qw () ou ce que rien.


@OOESOR - Vous n'utilisez pas le temps de Sinan :: Module de machine. Mon commentaire visait le libellé original de la question (avant la modification de Brian) qui a déclaré My @a = "ABC, DEF, EFG, GHY, KLM, GHN"


QW "ABC DEF EFG GHY KLM GHN" est correct.



1
votes
my @a = qw' abc def efg ghy klm ghn ';
my @b = qw' def ghy jgk lom com klm ';

my $flag;

foreach  my $item(@a) {
  $flag = @b~~$item ? 0 : 1;
  last if !$flag;
}
Note that you will need Perl 5.10, or later, to use the smart match operator (~~) .

3 commentaires

@Dvk, je ne sais pas. J'ai appris cela de l'apprentissage de Perl. Je n'ai pas besoin de l'utilisation 5.010; déclaration mais peut-être que ce n'est que fonctionnel après Perl 5.10. Je vérifierai. Je suis toujours un apprenant Perl. Veuillez me corriger si quelque chose a mal tourné :)


@DVK, le livre dit "Opérateur Smart Match de Perl 5.10's". Mais on dirait que je n'ai pas à utiliser l'utilisation 5.010; déclaration. Juste la tester à nouveau et l'utilisation 5.010; La déclaration est inutile au moins avec ActiveperL 5.10.0 sur WinXP. Mais je suppose que cela ne fonctionnera pas avant Perl 5.10.


Bien que je ne voie pas d'erreurs de débutants criantes, je ne pense pas que cela fonctionnera correctement tout le temps.



1
votes

de l'exigence selon laquelle "si tout em> correspondance d'élément", utilisez l'intersection des ensembles:

sub set{
  my %set = map { $_, undef }, @_;
  return sort keys %set;
}
sub compare{
    my ($listA,$listB) = @_;
    return ( (set(@$listA)-set(@$listB)) > 0)
}


5 commentaires

Cette question est marquée "Perl". Je ne veux pas vous dire sans vous avertir de vous en premier ...


Aucune question n'est entièrement spécifique à la langue. Je suis sûr que quelqu'un peut proposer une version Perl. Il illustre également le point général.


Oui, mais si un débutant voit votre réponse, dans ce fil étiqueté Perl, sans aucune notification qu'il n'est pas une réponse de Perl, et les tape dans, puis se demande pourquoi cela ne fonctionne pas? La seule chose responsable à faire avec cette réponse est de la descendre. Pardon.


@Brad: Cheers, ça ressemble à un beau morceau. Je suis surpris qu'il n'y ait pas un module intégré / largement disponible pour les ensembles ...


J'ai enlevé mon bowvote. Il y a encore un bowvote mais ce n'est pas à moi.



2
votes

Ceci est un moyen: xxx


3 commentaires

Pas la lecture la plus facile mais je l'aime. Lorsque je répondais à une question, j'aime expliquer plus de comportement hors tout, nous apprenons cependant que nous apprenons cependant.


Quelqu'un peut-il expliquer "@a {@a} = (1) x @a;"?


Il remplit les clés de % A avec les éléments de @a , et les valeurs sont toutes 1. Ceci exploite l'allocation de Perl de différents types de variables avec le même nom, le hachage Trancher et un tableau dans un contexte scalaire. Cependant, ce code ne fonctionnera pas pour la comparaison de tableaux avec des valeurs non uniques.



0
votes

La force brute devrait faire l'affaire pour le petit A N : xxx

pour un grand n , utilisez une table de hachage: < / p> xxx

où un grand n est | @A | + | @b | > ~ 1000 éléments


0 commentaires

4
votes

Cocher Pour créer une fonction d'intersect, qui retournera une liste d'éléments présents dans les deux listes. Ensuite, votre valeur de retour dépend du nombre d'éléments de la liste intersectée.

Vous pouvez facilement trouver sur le Web la meilleure mise en œuvre de l'intersect pour Perl. Je me souviens de la chercher il y a quelques années.

Voici ce que j'ai trouvé: xxx


0 commentaires

0
votes

IMHO, vous devriez utiliser Liste :: POWise . Toutefois, si, pour une raison quelconque, vous ne pouvez pas, alors le SUB suivant reviendrait un 1 pour chaque index où la valeur dans la première matrice se compare égale à la valeur dans le second tableau. Vous pouvez généraliser cette méthode autant que vous le souhaitez et transmettre votre propre comparateur si vous voulez, mais à ce stade, il suffit d'installer Liste :: PROMUTILS serait une utilisation plus productive de votre temps. xxx


0 commentaires

0
votes

C'est Perl. La solution "évidente": xxx

donné "\ 0" n'étant pas dans @a.

Mais merci de confirmer qu'il n'y a pas d'autre solution générique que de rouler votre propre .


0 commentaires

0
votes
my @a1 = qw|a b c d|;
my @a2 = qw|b c d e|;

for my $i (0..$#a1) {
    say "element $i of array 1 was not found in array 2" 
        unless grep {$_ eq $a1[$i]} @a2
}

0 commentaires

0
votes

Si vous envisagez les tableaux avec une commande différente d'être différente, vous pouvez utiliser Array: : Diff xxx


0 commentaires

0
votes

Cette question pourrait toujours signifier deux choses où elle indique "si un élément correspond à un drapeau":

  1. éléments à la même position, i.e $ A [2] eq $ b [2] li>
  2. valeurs à n'importe quelle position, c'est-à-dire $ A [3] EQ $ B [5] li> ol>

    Pour le boîtier 1, vous pouvez le faire: P>

    # make a hash of @a and check if any @b are in there
    my %a = map { $_ => 1 } @a;
    my @matches = grep { $a{$_} } @b;
    
    # set flag if there's matches at any position 
    my $flag = 1 if @matches;
    


0 commentaires