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

Algorithmes et structures de données Discussion :

[décalage d'une liste] Cherche mieux que l'algo naïf


Sujet :

Algorithmes et structures de données

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    187
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 187
    Points : 126
    Points
    126
    Par défaut [décalage d'une liste] Cherche mieux que l'algo naïf
    Bonjour,
    je cherche à décaler tous les éléments d'une liste, de n pas vers la droite mais je n'ai trouvé que l'algo naîf (j'ai honte d'être aussi nul )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    decalage(liste,m) :
    debut
    |   pour i de 0 à m faire
    |   |   pour j 0 à card(liste) de  faire
    |   |   |   si j = card(liste)-1 faire 
    |   |   |   |   liste[0] <- liste[card(liste)-1]
    |   |   |   sinon 
    |   |   |   |   liste[j+1] <- liste[j]
    |   |   |   fin si
    |   |   fin pour
    |   fin pour
    fin
    Voila, donc si n est le cardinal de liste, j'aimerais faire un peu mieux que O(m*n)
    Merci d'avance.
    Seulement le tout venant a été piraté par les mômes... Qu'est-ce qu'on fait, on s' risque sur le bizard ???

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    187
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 187
    Points : 126
    Points
    126
    Par défaut
    Oups, je viens de m'apperçevoir que cet algo ne fonctionne pas du tout.
    Je vais donc revoir mes prétentions à la baisse, je suis preneur même en O(nm) .
    Seulement le tout venant a été piraté par les mômes... Qu'est-ce qu'on fait, on s' risque sur le bizard ???

  3. #3
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    c'est un tableau, par construction ?

    Parce que sinon tu aurais vraisemblablement intérêt justement à utiliser une liste....
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    187
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 187
    Points : 126
    Points
    126
    Par défaut
    Oui c'est un tableau mais pour moi une liste et un tableau c'est le même combat dans ce cas là non?
    J'ai quand même trouver un algo en n*m mais j'aimerais vraiment faire mieux parce qu'avec 1 millon d'éléments c'est un peu long
    Seulement le tout venant a été piraté par les mômes... Qu'est-ce qu'on fait, on s' risque sur le bizard ???

  5. #5
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par tom42
    Oui c'est un tableau mais pour moi une liste et un tableau c'est le même combat dans ce cas là non?
    Non pas du tout....

    • Avec un tableau, le seul autre moyen (qui peut être très rapide), c'est un déplacement mémoire direct (je ne sais pas avec quel langage tu programmes, mais ça se fait sans doute dans tous. En C c'est avec la fonction memmove ) :

      • stocker l'adresse de l'élément du tableau qu'on supprime
      • déplacer d'un coup le bloc mémoire partant de l'élément suivant jusqu'à la fin à cette adresse



    • Sinon, si c'est avec une liste :

      • un element d'une liste est constitué des données, et d'un pointeur vers l'élément suivant et sur l'élément précédent
      • donc pour supprimer, il suffit d'ajuster le suivant du précédent et le précédent du suivant (et de libérer ce qui doit l'être de l'élément supprimé).

    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  6. #6
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par tom42
    Oui c'est un tableau mais pour moi une liste et un tableau c'est le même combat dans ce cas là non?
    J'ai quand même trouver un algo en n*m mais j'aimerais vraiment faire mieux parce qu'avec 1 millon d'éléments c'est un peu long
    Plutot que m blocs de 1 element, imagine que tu as a deplacer 1 bloc de m elements...
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  7. #7
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    j'avais pas complètement lu. Tu veux décaler vers la droite, c'est à dire insérer.

    La même technique que ci-dessus :

    avec un tableau, déplacement mémoire de m places (1 opération, mais gros mouvement de mémoire, donc possibilité crash (ça dépend si tu as déjà reservé la mémoire) ou lenteur éventuelle), mas certainement plus rapide que le décalage manuel.

    avec une liste : insertion de m éléments, avec ajustement des précédents et suivant à chaque fois (3*m opérations).
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  8. #8
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par souviron34
    j'avais pas complètement lu. Tu veux décaler vers la droite, c'est à dire insérer.
    Je me demande s'il ne veut pas un decalage circulaire.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    187
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 187
    Points : 126
    Points
    126
    Par défaut
    Merci pour vos réponses. Ca me revient maintenant (désolé mais mes cours d'algo sont loin dériére moi.. )

    Cela dit, j'implémente cela avec actionscript de flash alors pour ce qui est des memcpy et des allocations de mémoire, je peux oublier.
    Ma structure de donnée est forcemment une table et je ne peux accéder qu'à un un élément à la fois.
    Est-ce donc mort pour améliorer la complexité?
    Seulement le tout venant a été piraté par les mômes... Qu'est-ce qu'on fait, on s' risque sur le bizard ???

  10. #10
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    And now... Ladies and Gentlemen, the big shift in o(n) !

    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
    /**
     * @param arr le tableau a decaler
     * @param n la longueur du tableau
     * @param r le nombre de decalage a droite
     */
    void shift(int[] arr, int n, int r) {
     
    	// pour le cas ou r > n
    	r=r%n;
    	if (r<=0) return;
     
    	// creation du tableau "tampon"
    	int[] backlog = new int[r];
     
    	// remplissage initial du tampon
    	for(int i=0;i<r;i++)
    		backlog[i]=arr[i];
     
    	// boucle d'echanges tableau/tampon
    	for(int i=r;i<n+r;i+=r) {
    		for(int j=0;j<r;j++) {
    			int tmp=arr[(i+j)%n];
    			arr[(i+j)%n]=backlog[j];
    			backlog[j]=tmp;
    		}
    	}
    }

    Citation Envoyé par Jean-Marc.Bourguet
    Plutot que m blocs de 1 element, imagine que tu as a deplacer 1 bloc de m elements...
    En fait, tu déplaces n/m blocs de m elements !
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  11. #11
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    ben à ce compte là il y a encore plus simple : (en O(n-pos))


    n = taille actuelle du tableau
    pos = emplacement où insérer
    m = nombre d'éléments à insérer

    pour i = (n+m) jusquà i = (pos+m) par incrément de -1, faire
    table[i] = table[i-m]



    @pseudocode : tu te compliques la vie
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    187
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 187
    Points : 126
    Points
    126
    Par défaut
    En fait je ne voulais pas inserer d'élément mais tous les décaler vers la droite de r.
    Je viens d'implémenter l'algo "shift" et ça va plus vite.

    Voila merci à tous pour vos réponses
    Seulement le tout venant a été piraté par les mômes... Qu'est-ce qu'on fait, on s' risque sur le bizard ???

  13. #13
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    as you wish...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  14. #14
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par souviron34
    ben à ce compte là il y a encore plus simple : (en O(n-pos))

    n = taille actuelle du tableau
    pos = emplacement où insérer
    m = nombre d'éléments à insérer

    pour i = (n+m) jusquà i = (pos+m) par incrément de -1, faire
    table[i] = table[i-m]
    Hum... ca fait un shift circulaire ca ?


    Je viens d'implémenter l'algo "shift" et ça va plus vite.
    Je l'ai appelé "shift" comme ca. Ce n'est pas un algo "officiel" standard et reconnu.... juste le résultat de mes 30 secondes de reflexion....
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  15. #15
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par pseudocode
    Hum... ca fait un shift circulaire ca ?
    le PO n'a pas parlé d'un shift circulaire du tout, mais de décaler les éléments vers la droite....
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  16. #16
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut Humour ! Humour ! Humour ! Humour !
    Citation Envoyé par souviron34
    le PO n'a pas parlé d'un shift circulaire du tout, mais de décaler les éléments vers la droite....
    Ah bah, bien sur, si tu fais confiance au posteurs... Comme si les gens savaient ce qu'ils veulent, et qu'ils l'exprimaient clairement.

    Heureusement, cette fois ci il y avait du pseudocode () ce qui m'a permis de déchiffrer la veritable question.

    si j = card(liste)-1 faire
    liste[0] <- liste[card(liste)-1]
    sinon
    liste[j+1] <- liste[j]
    fin si
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  17. #17
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    187
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 187
    Points : 126
    Points
    126
    Par défaut
    Pardon souviron34 si je me suis mal exprimé mais c'est bien un "shift circulaire" que je voulais faire.
    En tout cas meci et félicitation pour la performance de ce forum.
    Seulement le tout venant a été piraté par les mômes... Qu'est-ce qu'on fait, on s' risque sur le bizard ???

  18. #18
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par souviron34
    @pseudocode : tu te compliques la vie
    Tu ais completement raison. Il y a plus simple, avec juste un décalage.

    Il suffit de faire un décalage a droite dans le tableau, en ayant auparavant sauvegardées les valeurs qui vont etre écrasées. Puis de remettre ces valeurs a gauche. exemple avec un décalage de 2 a droite:

    Tableau initial
    [1|2|3|4|5|6|7|8|9]

    On sauve les 2 elements de droite
    [1|2|3|4|5|6|7|8|9] ___tmp=[8|9]

    On décale les elements du tableau
    [ | |1|2|3|4|5|6|7] ___tmp=[8|9]

    On recopie les valeurs sauvées a gauche
    [8|9|1|2|3|4|5|6|7]


    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
     
    /**
     * @param arr le tableau a decaler
     * @param n la longueur du tableau
     * @param r le nombre de decalage a droite
     */
    private void shift(int[] arr, int n, int r) {
    	// cas ou R > N
    	r=r%n;
    	if (r<=0) return;
     
    	// sauvegarde des valeurs qui vont etre écrasées par le décalage
    	int[] backlog = new int[r];
    	for(int i=0;i<r;i++) backlog[i]=arr[n-r+i];
     
    	// decalage des elements du tableau a droite 
    	for(int i=n-1;i>=r;i--) arr[i]=arr[i-r];
     
    	// recopie des valeurs sauvegardées
    	for(int i=0;i<r;i++) arr[i]=backlog[i];
    }
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  19. #19
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  20. #20
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut et on peut se passer du tampon !!
    Et on peut aussi se passer du tampon :



    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
     
    /**
     * @param arr le tableau a decaler
     * @param n la longueur du tableau
     * @param r le nombre de decalage a droite
     */
    private void shift(int[] arr, int n, int r) {
    int i, j ;
    int tmp ;
    int tmp1 ;
     
           // cas ou R > N
           r=r%n;
           if (r<=0) return;
     
    	// decalage des elements du tableau a droite 
    	for( i=0 ; i < r ; i++ )
    	  {
    	    j = i + r ;
    	    tmp1 = arr[i] ;
     
    	    while ( j < n )
    	      {
    		tmp = arr[j] ;
    		arr|j] = tmp1 ;
    	        tmp1 = tmp ;
     
    		j = j + r ;
    	      }
     
    	    if ( j >= n )
    	      {
    		j = j % n ;
    		arr[j] = tmp1 ;
    	      }
              }
    }

    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 2
    Dernier message: 29/05/2009, 10h16
  2. [IE]Décalage important lors de l'affichage d'une list verticale
    Par Macintoc dans le forum Mise en page CSS
    Réponses: 7
    Dernier message: 13/04/2007, 10h09
  3. Réponses: 6
    Dernier message: 22/11/2006, 20h04
  4. Réponses: 6
    Dernier message: 16/05/2006, 16h17

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