IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Tri spécial sur un tableau


Sujet :

Langage Perl

  1. #1
    Membre du Club
    Femme Profil pro
    ingénieur d'étude en bioinformatique
    Inscrit en
    Février 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : ingénieur d'étude en bioinformatique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2011
    Messages : 45
    Points : 43
    Points
    43
    Par défaut Tri spécial sur un tableau
    Bonjour,
    J'ai un problème avec un de mes scripts. Il faut que je trie un tableau dans l'ordre alphabétique, mais en prenant en compte d'abord les caractères spéciaux (il n'y aurait que _ ), ensuite les lettres, puis enfin les chiffres.

    Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    LTR1
    LTR1_
    LTR1A
    LTR1B
    LTR10
    LTR11
    LTR2
    ...
    Je ne vois pas trop comment procéder et j'ai l'impression que la fonction sort ne permet pas ce type de tri.

    Merci d'avance.

    Laura.

  2. #2
    Membre éclairé Avatar de messinese
    Homme Profil pro
    IT Security Consultant
    Inscrit en
    Septembre 2007
    Messages
    429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IT Security Consultant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2007
    Messages : 429
    Points : 876
    Points
    876
    Par défaut
    Bonjour,

    ton exemple est il ce que tu souhaites en sortie ou ce que tu as en entrée ?

    Peux tu donner entrée/sortie afin de mieux coprendre ce que tu as et ce que tu doit obtenir stp ?

    merci

  3. #3
    Membre du Club
    Femme Profil pro
    ingénieur d'étude en bioinformatique
    Inscrit en
    Février 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : ingénieur d'étude en bioinformatique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2011
    Messages : 45
    Points : 43
    Points
    43
    Par défaut
    Mon exemple est ce que je veux en sortie.

    Ce que j'ai en entrée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    LTR1
    LTR10
    LTR11
    LTR1A
    LTR1B
    LTR1_
    LTR2
    Ce que j'aimerais en sortie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    LTR1
    LTR1_
    LTR1A
    LTR1B
    LTR10
    LTR11
    LTR2
    Merci pour votre aide !

  4. #4
    Membre éclairé Avatar de messinese
    Homme Profil pro
    IT Security Consultant
    Inscrit en
    Septembre 2007
    Messages
    429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IT Security Consultant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2007
    Messages : 429
    Points : 876
    Points
    876
    Par défaut
    Re,

    voici un exemple qui semble marcher, vous me direz si ceci vous convient sachant qu'il s'agit ici d'un exmple à modifier au besoin bien entendu:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    #! /usr/bin/perl
     
    use 5.10.0;
    use strict;
    use warnings;
    use diagnostics;
     
    use constant TRUE  => (1);
    use constant FALSE => (0);
     
    my $Compteur    = TRUE;
    my $SpecialChar = (FALSE);
    my @Tableau1    = (
                       "LTR1",
                       "LTR10",
                       "LTR11",
                       "LTR1A",
                       "LTR1B",
                       "LTR1_",
                       "LTR2",
                      );
    my (@FinalTab, @SortedTab) = ();
     
    BEGIN:
     
    say ("[*] Debut du traitement");
     
    foreach my $lines(sort(@Tableau1)){
     
        # On récupere la ligne contenant notre caractere spécial
        if ($lines =~ /[_]/) {
            $SpecialChar = $lines;
            next;
        }
        push (@FinalTab, $lines);
    }
     
    foreach my $lines(@FinalTab){
     
        # On place la ligne contenant le caractere spécial avant LTR10
        if ($lines =~ /[0]/) {
            push(@SortedTab, $SpecialChar);
            my $Char =$SpecialChar;
            $SpecialChar =~ s/$Char//g;
        }
        push(@SortedTab,$lines);
    }
     
     
    foreach my $Sorted(@SortedTab){
     
        # On affiche le tableau trié
        say ("Boucle N. $Compteur = $Sorted");
        $Compteur++;
    }
     
    say ("[*] Fin du traitement");
    exit(TRUE);
    Ce qui retourne cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [*] Debut du traitement
    Boucle N. 1 = LTR1
    Boucle N. 2 = LTR1_
    Boucle N. 2 = LTR10
    Boucle N. 3 = LTR11
    Boucle N. 4 = LTR1A
    Boucle N. 5 = LTR1B
    Boucle N. 6 = LTR2
    [*] Fin du traitement
    Edit: aprés relecture je vois que les A,B etc.. se trouvent etre sous les 10,11 .. il faudra donc modifier ce code afin que tu obtienne réellement ce que tu veux, encore désolé mais la je n'ai pas trop le temps de m'y repencher ... :/
    Cdlt.

  5. #5
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Tu peux tout à fait utiliser la fonction sort, mais je pense que tu vas devoir écrire toi-même la fonction de comparaison appelée par la fonction sort.

    La syntaxe est du type:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    my @sorted_array = sort ma_fonction_comparaison @unsorted;
     
    sub ma_fonction_comparaison {
         # compare les variables spéciales $a et $b 
    }
    Ta fonction devra comparer $a et $b selon les règles que tu as énoncées et renvoyer -1 si $a doit être avant $b, + 1 si $b doit être avant $a, et 0 si les $a = $b.

  6. #6
    Membre du Club
    Femme Profil pro
    ingénieur d'étude en bioinformatique
    Inscrit en
    Février 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : ingénieur d'étude en bioinformatique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2011
    Messages : 45
    Points : 43
    Points
    43
    Par défaut
    Merci pour vos réponses.
    J'ai du coup utilisé la méthode de Lolo78, plus facile à mon goût. De plus, l'autre méthode proposée ne triait pas exactement comme je le souhaitais.

    Du coup le code ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #!usr/bin/perl
     
    use strict ;
    use warnings ;
    use Scalar::Util qw(looks_like_number);
     
    sub tri_special {
    	# compare les variables spéciales $a et $b
    	if ($a eq $b) {return 0 ;}
    	elsif ($a eq "_"){return -1 ;}
    	elsif ($b eq "_"){return 1 ;}
    	elsif (looks_like_number($a) and looks_like_number($b))
    	{
    		if ($a lt $b){return -1 ;}
    		elsif ($a gt $b){return 1 ; }
    	}
    	elsif (!looks_like_number($a) and !looks_like_number($b))
    	{
    		if ($a<$b){return -1 ;}
    		elsif ($a>$b){return 1 ;}
    	}
    	elsif (looks_like_number($a) and !looks_like_number($b))
    	{
    		return 1 ;
    	}
    	elsif (!looks_like_number($a) and looks_like_number($b))
    	{
    		return -1 ;
    	}
    }
     
    my @dico = ("LTR1","LTR10","LTR11","LTR1A","LTR1B","LTR1_","LTR2") ;
    my @dico_tri ;
    for (my $i=0;$i<$#dico-1;$i++)
    {
    	print "## $dico[$i] ##\n" ;
    	my @tmp ;
    	for (my $j=$i+1;$j<$#dico;$j++)
    	{
    		if ($dico[$j] =~ m/^$dico[$i](.*)$/)
    		{
    			push(@tmp,$1) ;
    		}
    	}
    	print join ("\t",@tmp)."\n" ;
    	my @tmp_tri = sort tri_special @tmp ;
    	print join ("\t",@tmp_tri)."\n" ;
    }
    Je pense que l'écriture peut être améliorée...
    Sur un petit exemple ça marche. J'attends de voir si sur un exemple plus complexe ca marche également et je mettrais à ce moment-là la mention "Résolu".

    Merci encore pour votre aide !

    Laura.

  7. #7
    Membre du Club
    Femme Profil pro
    ingénieur d'étude en bioinformatique
    Inscrit en
    Février 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : ingénieur d'étude en bioinformatique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2011
    Messages : 45
    Points : 43
    Points
    43
    Par défaut
    En fait le script ne marche pas comme je veux...
    Dès que je regarde sur l'ensemble du tableau, ça ne marche plus, dû au fait que les mots ne sont triés que par ordre alphabétique (car ils sont considérés comme le cas ligne 17 du script précédent).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    # avec la meme fonction tri_special que précédemment
    my @dico = ("LTR1","LTR10","LTR11","LTR1A","LTR1B","LTR1_","LTR2") ;
    print join ("\t",@dico)."\n" ;
    my @dico_tri = sort tri_special @dico ;
    print join ("\t",@dico_tri)."\n" ;
    J'essaye de trouver une solution, mais si vous en avez une je suis preneuse !

    Merci encore de votre aide.

  8. #8
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    J'étais aussi surpris de lire ton message disant que le code présentaé fonctionnait, ça ne me paraissait pas possible.

    En fait je pense que tu ne peux pas échapper au fait de splitter chacun des deux mots à comparer par lettre, et de comparer les lettres au fur et à mesure.

    Par ailleurs, en dehors du fait qu'il ne fait pas exactement ce dont tu as besoin, le code ci-dessous:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	if ($a eq $b) {return 0 ;}
    	elsif ($a eq "_"){return -1 ;}
    	elsif ($b eq "_"){return 1 ;}
    peut se réécrire plus simplement, sans les else, les parenthèses et les accolades comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	return 0 if $a eq $b;
    	return -1 if $a eq "_";
    	return 1 if $b eq "_";

  9. #9
    Membre du Club
    Femme Profil pro
    ingénieur d'étude en bioinformatique
    Inscrit en
    Février 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : ingénieur d'étude en bioinformatique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2011
    Messages : 45
    Points : 43
    Points
    43
    Par défaut
    J'essayerais demain ta méthode avec le split avant de comparer caractère par caractère.

    Merci encore !

Discussions similaires

  1. Tri rapide sur un tableau d'entiers
    Par eldoir dans le forum Shell et commandes GNU
    Réponses: 46
    Dernier message: 03/07/2015, 12h02
  2. [PHP 5.3] Tri spécifique sur un tableau
    Par zouberi dans le forum Langage
    Réponses: 4
    Dernier message: 06/10/2011, 09h22
  3. Tri spécial sur JS existant
    Par Isiker dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 21/11/2010, 20h34
  4. [Tableaux] tri sur un tableau multi-dimensionnel
    Par nicoaix dans le forum Langage
    Réponses: 1
    Dernier message: 12/04/2006, 21h23
  5. Réponses: 2
    Dernier message: 08/04/2004, 16h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo