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 :

problème algo boulot


Sujet :

Algorithmes et structures de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2023
    Messages
    78
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2023
    Messages : 78
    Par défaut problème algo boulot
    Salut a tous,

    tout est dans le titre. J'ai de tres serieux problemes de logique, ca veut pas rentrer dans ma tete, et si ca rentre c'est par par coeurisme a force de refaire 10 fois le meme exercice.
    La pour le boulot j'ai un algorithme a faire et je suis coincé. en gros voici le probleme:

    J'ai une table contratComponent avec une colonne ordre (int). j'ai plusieurs contrats avec leurs numeros d'ordre. je dois pouvoir modifier l'ordre.

    ex. liste de 5 components.
    components = [
    {id: "comp1", order: 1},
    {id: "comp2", order: 2},
    {id: "comp3", order: 3},
    {id: "comp4", order: 4}.
    {id: "comp5", order: 5}
    ];
    le component a changer est comp2 qui avait order = 2 et maintenant son newOrder = 3

    {id: "comp2", order: 2} > {id: "comp2", order: 3}
    1) liste triee avec comp2 enlevé:

    components = [
    {id: "comp1", order: 1},
    {id: "comp3", order: 3},
    {id: "comp4", order: 4}.
    {id: "comp5", order: 5}
    ];


    2) je decremente les ordres qui viennent apres comp2

    components = [
    {id: "comp1", order: 1},
    {id: "comp3", order: 2},
    {id: "comp4", order: 3}.
    {id: "comp5", order: 4}
    ];


    3) dans la liste il y avait deja un order = 3

    {id: "comp3", order: 3} (qui est devenu {id: "comp3", order: 2})

    4) donc j'incremente les order suivants

    components = [
    {id: "comp1", order: 1},
    {id: "comp3", order: 2},
    {id: "comp4", order: 4}.
    {id: "comp5", order: 5}
    ];

    5) je reinsere le component comp2 avec le newOrder:

    components = [
    {id: "comp1", order: 1},
    {id: "comp3", order: 2},
    {id: "comp2", order: 3},
    {id: "comp4", order: 4}.
    {id: "comp5", order: 5}
    ];


    moi j'ai fait ca:

    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
    public void SetOrder(ref Contract contract, Guid contractComponentId, int newOrder)
    {
        ContractComponent? componentToMove = contract.ContractComponents
            .FirstOrDefault(c => c.Id == contractComponentId);
     
        List<ContractComponent> componentsListWithoutComponentToMove = contract.ContractComponents
            .Where(c => c.Id != contractComponentId)
            .OrderBy(c => c.Order)
            .ToList();
     
        if (componentToMove == null) return;
     
        int oldOrder = componentToMove.Order;
        //if (oldOrder == newOrder) return;
     
        if (newOrder > oldOrder)
        {
            foreach (var component in componentsListWithoutComponentToMove
                .Where(c => c.Order > oldOrder && c.Order <= newOrder))
            {
                component.Order -= 1;
            }
        }
        else
        {
            foreach (var component in componentsListWithoutComponentToMove
                .Where(c => c.Order >= newOrder && c.Order < oldOrder))
            {
                component.Order += 1;
            }
        }
     
        componentToMove.Order = newOrder;
     
        componentsListWithoutComponentToMove.Add(componentToMove);
     
        componentsListWithoutComponentToMove = componentsListWithoutComponentToMove
            .OrderBy(c => c.Order)
            .ToList();
     
        contract.ContractComponents = componentsListWithoutComponentToMove;
     
    }
    sauf que des l'entree de ma methode le contractComponent que je veux modifer a deja le newOrder et donc l'algo ne marche pas. Vous avez une idee de comment faire? Je suis desespere

  2. #2
    Membre Expert
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    676
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 95
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 676
    Par défaut
    Salut,

    Un problème de logique, n'exagérons rien. Qu'est-ce qui t'a amené à l'algo que tu présentes.
    A-t-il un nom, d'où vient-il ? N'y avait-il rien de plus adapté dans la librairie (genre file de priorité (priority queue)) ?

    Est-ce que tes ordres sont uniques et se suivent (1,2,3,...) ? Si oui, est-ce que supprimer ton composant de ta liste triée pour le réinsérer à la position de ton choix, puis recalculer tes ordres (entre la position de départ et d'arrivée), ça pourrait faire l'affaire ?

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2023
    Messages
    78
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2023
    Messages : 78
    Par défaut
    salut,

    merci pour ta contribution. Alors l'exemple que j'ai donné m'a ete donné par mon boss, c'est ce qu'il veut que je fasse.

    Est-ce que tes ordres sont uniques et se suivent (1,2,3,...) ? Si oui, est-ce que supprimer ton composant de ta liste triée pour le réinsérer à la position de ton choix, puis recalculer tes ordres (entre la position de départ et d'arrivée), ça pourrait faire l'affaire ?
    Oui je pense que c'est ca mais je sais pas le faire. j'ai pondu ca en essayant de suivre son exemple mais c'est pas bon:

    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
    59
    public void SetOrder(ref Contract contract, Guid contractComponentId, int newOrder)
    {
        // je get mon composant
        ContractComponent? componentToMove = contract.ContractComponents
            .FirstOrDefault(c => c.Id == contractComponentId);
     
        if (componentToMove == null) return; 
     
        // liste des composants sans mon composant
        List<ContractComponent> componentsListWithoutComponentToMove = contract.ContractComponents
            .Where(c => c.Id != contractComponentId)
            .OrderBy(c => c.Order)
            .ToList();
     
        // je decremente les composants qui viennent apres le miens
        foreach (var contractComponent in componentsListWithoutComponentToMove)
        {
            if(contractComponent.Order > componentToMove.Order)
            {
                contractComponent.Order -= 1;
     
            }
        }
     
        //j'incremente les composants qui viennent apres le miens
        foreach (var contractComponent in componentsListWithoutComponentToMove)
        {
            if (contractComponent.Order == newOrder || contractComponent.Order > newOrder)
            {
                contractComponent.Order += 1;
            }
        }
     
        //je decremente les composants qui viennent apres le miens
        foreach (var contractComponent in componentsListWithoutComponentToMove)
        {
            if (contractComponent.Order == newOrder || contractComponent.Order < newOrder)
            {
                contractComponent.Order -= 1;
                if (contractComponent.Order == 1)
                {
                    contractComponent.Order = 1;
                }
            }
        }
     
        componentToMove.Order = newOrder;
     
        // je remets le composant dans la liste
        componentsListWithoutComponentToMove.Add(componentToMove);
     
        // je trie la liste
        componentsListWithoutComponentToMove = componentsListWithoutComponentToMove
            .OrderBy(c => c.Order)
            .ToList();
     
        // je mets a jour la liste des composants
        contract.ContractComponents = componentsListWithoutComponentToMove;
    }

  4. #4
    Membre Expert
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    676
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 95
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 676
    Par défaut
    Je ne connais pas csharp, mais je vois que tu utilises une collection list, elle propose les méthodes RemoveAt() et Insert(), laisse la faire le travail pour toi.

    essaye :
    Code pseudo-code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //on suppose mylist triée, sinon le faire.
    //mylist.sort_by_order()
     
    index_of_contractComponentId= order_of_contractComponentId - 1; // car l'index commence à 0 (order - 1)
    mylist.RemoveAt(index_of_contractComponentId);
     
    new_index_of_contractComponentId= newOrder - 1;
    mylist.Insert(new_index_of_contractComponentId, {contractComponentId, newOrder});
     
    index_min= Min(index_of_contractComponentId, new_index_of_contractComponentId);
    index_max= Max(index_of_contractComponentId, new_index_of_contractComponentId);
    for index= index_min to index_max
        mylist[index].Order= index + 1;

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2023
    Messages
    78
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2023
    Messages : 78
    Par défaut
    ok je vais essayer si ca marche.

  6. #6
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 221
    Par défaut
    ok, je viens de comprendre cette phrase, en tout cas, je pense : sauf que des l'entree de ma methode le contractComponent que je veux modifer a deja le newOrder et donc l'algo ne marche pas

    En fait, il y a une autre procédure qui tourne AVANT tout ça, et qui modifie la valeur Order pour le ContractComponent à déplacer.
    Et donc l'instruction en ligne 13 oldOrder = componentToMove.Order; renvoie une valeur fausse, elle renvoie NewOrder.

    Le reste de ton programme me paraît correct ; on ne va pas le réécrire. Mais à la place de cette ligne 13, il va falloir trouver un truc pour calculer oldOrder.

    en ligne 13, tu auras donc int oldOrder = CalculeOldOrder(componentsListWithoutComponentToMove )

    Et ta procédure CalculeOldOrder pourrait être quelque chose du genre (pseudo code, je ne connais pas du tout la syntaxe de ton langage) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procédure  CalculeOldOrder (componentsListWithoutComponentToMove )
    i=1
    fini = False 
    tantque fini = False
        faire une boucle pour voir si il y a un élément tel que Order=i
        si oui alors 
           i=i+1
        sinon
           return (i)
        fin
    fin

    Dans tout ça, on suppose que les n°s Order sont tous utilisés.


    Edit : je n'avais pas vu tous les messages ... la piste de Kaitlyn me semble plus professionnelle que notre bricolage.

  7. #7
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2023
    Messages
    78
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2023
    Messages : 78
    Par défaut
    alors en fait le lead m'a dit que c'est normal que le contractComponentToMove ait la nouvelle valeur de Order (newOrder).


    @ Kaitlyn: j'ai essayé ta solution:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //on suppose mylist triée, sinon le faire.
    //mylist.sort_by_order()
     
    index_of_contractComponentId= order_of_contractComponentId - 1; // car l'index commence à 0 (order - 1)
    mylist.RemoveAt(index_of_contractComponentId);
     
    new_index_of_contractComponentId= newOrder - 1;
    mylist.Insert(new_index_of_contractComponentId, {contractComponentId, newOrder});
     
    index_min= Min(index_of_contractComponentId, new_index_of_contractComponentId);
    index_max= Max(index_of_contractComponentId, new_index_of_contractComponentId);
    for index= index_min to index_max
        mylist[index].Order= index + 1;
    malheureusement elle marche pas:

    j'ai dans ma bdd 3 components:

    component 1: ordre 1
    component 2: ordre 2
    component 3: ordre 3

    je veux donner l'ordre 3 au component 1.

    en appliquant ton code le resultat est:
    component 1 : ordre 3
    component 2: ordre 2
    component 3: ordre 2

    ce qui est pas bon

  8. #8
    Membre Expert
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    676
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 95
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 676
    Par défaut
    Citation Envoyé par gotax Voir le message
    @ Kaitlyn: j'ai essayé ta solution:
    .../...
    malheureusement elle marche pas:

    j'ai dans ma bdd 3 components:

    component 1: ordre 1
    component 2: ordre 2
    component 3: ordre 3

    je veux donner l'ordre 3 au component 1.

    en appliquant ton code le resultat est:
    component 1 : ordre 3
    component 2: ordre 2
    component 3: ordre 2

    ce qui est pas bon
    Je veux bien, mais où est le code ?

  9. #9
    Membre Expert
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    676
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 95
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 676
    Par défaut
    code édité et exécuté sur https://www.onlinegdb.com/online_csharp_compiler
    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
    /******************************************************************************
     
                                Online C# Compiler.
                    Code, Compile, Run and Debug C# program online.
    Write your code in this editor and press "Run" button to execute it.
     
    *******************************************************************************/
     
    using System;
    using System.Collections.Generic;
     
    class HelloWorld {
     
    class Component {
        public string id { get; set; }
        public int order { get; set; }
    }
     
    static void print_mylist(List<Component> mylist) {
        mylist.ForEach(comp => Console.WriteLine("{0},{1}", comp.id, comp.order));
        Console.WriteLine();
    }
     
    static void Main() 
    {
        var mylist= new List<Component> {
              new Component() {id="comp1", order=1}
            , new Component() {id="comp2", order=2}
            , new Component() {id="comp3", order=3} 
        };
     
        var comp_id= "comp1";
        var new_order= 3;
     
        print_mylist(mylist);
        //=================================================================
        var tmplist= new List<Component>(mylist); //protect the original list against invalidation
        var index_of_comp= tmplist.FindIndex(c => c.id.Equals(comp_id));
        var comp= tmplist[index_of_comp];
        tmplist.RemoveAt(index_of_comp);
     
        var new_index_of_comp= new_order-1;
        comp.order= new_order;
        tmplist.Insert(new_index_of_comp, comp);
     
        var start= Math.Min(index_of_comp, new_index_of_comp);
        var end= Math.Max(index_of_comp, new_index_of_comp);
        for (int i= start; i <= end; i++) {
            tmplist[i].order= i+1;
        }
        mylist= tmplist;
        //=================================================================
        print_mylist(mylist);
     
    }
    }
    output:
    comp1,1
    comp2,2
    comp3,3

    comp2,1
    comp3,2
    comp1,3

  10. #10
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 221
    Par défaut
    Si tu veux repartir avec ton tout premier code... et juste changer la ligne 13 'calcul de oldOrder',

    Tu peux procéder ainsi :
    - Calculer la taille totale de ton tableau nLignes=taille totale du tableau
    - Calculer la somme de tous les Order sumOrder = Somme de tous les order

    Normalement, si tous les Order étaient tous les nombres entre 1 et nLignes, on obtiendrait sumOrder= (nLignes)(nLignes+1)/2
    Mais notre élément ComponentToMove n'a pas la bonne valeur Order, il a la valeur ComponentToMove.order au lieu de oldOrder. et donc la somme qu'on trouve est (nLignes)(nLignes+1)/2 + ComponentToMove.order -oldOrder

    Et du coup, on peut retrouver oldOrder :

    oldOrder = (nLignes)(nLignes+1)/2 + ComponentToMove.order - sumOrder

    Du coup, tu dois remplacer ta ligne n°13 par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    nLignes = taille totale du tableau
    sumOrder = Somme de tous les order
    oldOrder = (nLignes)(nLignes+1)/2 + ComponentToMove.order - sumOrder

  11. #11
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 638
    Par défaut
    Bonjour,

    Je ne pratique pas C# aussi la difficulté m'échappe. Il y a 2 opérations, déplacement et renumérotation :
    • Déplacer le l'item choisi de sa place actuelle i à sa nouvelle place j. A défaut de l'existence d'un move, on peut effectivement en simuler un (extraction puis insert en supposant que l'insert prend la place et repousse l'actuel occupant vers l'indice supérieur).
    • Ensuite il faut renuméroter les ordres en séquence de i à j (si les indices de la liste commencent à 0, les ordres = indice + 1). Si la liste est préalablement triée et avec une séquence d'ordres sans trou, il faut éviter de modifier l'indice d'origine en ajoutant ou retranchant 1 car cela favorise les erreurs selon que l'ordre futur est supérieur ou inférieur à l'actuel.

    A vrai dire, l'utilité d'un ordre qui se contente de reprendre l'indice (éventuellement décalé de 1) dans la liste semble discutable. Rien ne semble empêcher la simulation de l'ordre en retournant l'indice. Mais peut être la liste est retriée parfois selon d'autres critères ?

    Salutations

  12. #12
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 672
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 672
    Par défaut
    Citation Envoyé par gotax Voir le message
    ex. liste de 5 components.
    components = [
    {id: "comp1", order: 1},
    {id: "comp2", order: 2},
    {id: "comp3", order: 3},
    {id: "comp4", order: 4}.
    {id: "comp5", order: 5}
    ];
    le component a changer est comp2 qui avait order = 2 et maintenant son newOrder = 3
    dans cet exemple, le changement d'ordre est que comp2 va au rang 3 donc comp3 va à l'ancienne place de comp2 et donc au final comp3 est au rang 2 ?
    si c'est bien ça, je dirais qu'il suffit d'échanger le rang avec le "comp" qui est déjà à la place du rang de destination.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. cherche algos Delphi pour : Huffman, R.S.A, D.E.S.
    Par X-Delphi dans le forum Débuter
    Réponses: 3
    Dernier message: 24/08/2002, 18h51
  2. Cherche l'algo crc 16 bits
    Par icepower dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 21/08/2002, 13h27
  3. Algo de calcul de FFT
    Par djlex03 dans le forum Traitement du signal
    Réponses: 15
    Dernier message: 02/08/2002, 17h45
  4. Algo de Hough et ou de Radon
    Par victorracine dans le forum Algorithmes et structures de données
    Réponses: 9
    Dernier message: 29/07/2002, 11h09
  5. Recherche algo tree
    Par Anonymous dans le forum Algorithmes et structures de données
    Réponses: 10
    Dernier message: 24/05/2002, 13h44

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