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

C# Discussion :

Génération de nombres au hasard sans répétition dans tableau en C#


Sujet :

C#

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2018
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Autre

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2018
    Messages : 12
    Points : 2
    Points
    2
    Par défaut Génération de nombres au hasard sans répétition dans tableau en C#
    j'aimerais bien remplir un tableau avec la fonction random mais sans avoir de répétition
    j'ai fais ce code mais il fonctionne pas
    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
     
    static void Main(string[] args)
            {
                int[] generer = new int[5];
                Random r = new Random();
                for (int i = 0; i < generer.Length; i++)
                {
                    generer[i] = r.Next(0, 35);
     
                    while (generer[i] == generer[i+1])
                    {
                        for(int j = 0; j < generer.Length; j++)
                        {
     
                            generer[j] = r.Next(0, 35);
                            Console.WriteLine(generer[i]);
     
                        }
                    }
     
                }

  2. #2
    Membre habitué
    Avatar de Benbout
    Homme Profil pro
    Avide de savoir
    Inscrit en
    Avril 2016
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Avide de savoir

    Informations forums :
    Inscription : Avril 2016
    Messages : 62
    Points : 142
    Points
    142
    Billets dans le blog
    1
    Par défaut
    Si l'utilisation de l'objet random n'est pas imposé, alors avec Linq tu peux t'en sortir avec grâce et sans efforts :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    static void Main(string[] args)
    {
        var array = Enumerable.Range(0, 10)     // la plage de nombres dans ta collection,
                .OrderBy(x => Guid.NewGuid())   // ordonné par rapport à un guid,
                .ToArray();                      // retour sous la forme d'un tableau.
    }
    Sans link, il faut s'accomoder d'un code qui sera un poil plus rapide à l’exécution (et encore, tout dépend de l’algorithme), mais aussi plus long à écrire et moins lisible.
    Dans le cas de ton code, tu sors des limites du tableaux durant ce while :
    while (generer[i] == generer[i + 1])

    L'index maximal de ton tableau est 4. Si i = 4, alors i + 1 te fera sortir du tableau et générera une erreur de type IndexOutOfRangeExpression.

    Tu sembles essayer de faire ton tableau random en pur calcul, sans passer par au moins une variable intermédiaire pour faire du swap. Je ne pense pas que ce soit possible.Un mathématicien serait le bienvenu pour confirmer ou invalider mon propos.

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2018
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Autre

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2018
    Messages : 12
    Points : 2
    Points
    2
    Par défaut
    oui en effet j'ai essayé de le faire avec une variable intermédiaire y pas plus d’erreur ,ça me génère des nombres aléatoires ,mais il y a quand même des répétition.
    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
     static void Main(string[] args)
            {
                Random r = new Random();
                int[] generer = new int[5];
     
     
                for (int i = 0; i < generer.Length; i++)
                {
                    int lNumber ;
     
     
                    do
                    {
     
                        lNumber = r.Next(1, 10);
                    }
                    while (genererr[i]==(lNumber));
                    genererr[i] = lNumber;
     
                    Console.Write("{0} ",generer[i]);
                }
                Console.ReadLine();

  4. #4
    Membre confirmé
    Avatar de nouanda
    Homme Profil pro
    Hobbyist
    Inscrit en
    Mai 2002
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Australie

    Informations professionnelles :
    Activité : Hobbyist

    Informations forums :
    Inscription : Mai 2002
    Messages : 246
    Points : 627
    Points
    627
    Par défaut
    C'est normal car tu ne vérifies pas si le nombre existe déjà dans ton tableau.
    Au passage, tu as une erreur de logique dans ta boucle while. Je t'invite a faire une exécution pas a pas pour essayer de la trouver! (indice: que contient ton tableau par défaut?).

    Pour créer un tableau sans doublon, il y a pleins de solutions:
    Utiliser une méthode pour vérifier si les nombre est déjà dans le tableau
    Utiliser un tableau externe pour stocker les nombres non déjà utilises et aller piocher dedans
    Remplir le tableau avec doublons et utiliser un tableau externe pour remplacer les doublons
    Utiliser purement Linq

    Les solutions ne manquent pas, a toi de voir celle qui te conviendra le mieux, chacune venant avec ses pour et ses contre.

    A mon avis, la première solution (méthode qui vérifie l’unicité) est la plus simple a mettre en oeuvre (si il te faut utiliser des arrays et random bien sur). Elle a cependant un gros caveat que je t'invite a trouver!

  5. #5
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    Une solution très simple pour parvenir à tes fins. L'idée est de stocker tes nombres dans un HashSet. Dans une boucle while, tant que la taille de la collection n'atteint pas une limite, tu génères un nombre et tu l'ajoutes.

    Ainsi, si le nombre n'est pas dans la collection, il est ajouté, et la taille de la collection augmente de 1. S'il est déjà présent, rien ne se passe (propriété de la collection HashSet) et on passe à l'itération suivante.

    A la fin, il reste éventuellement à convertir la collection en tableau, List ou tout autre collection de ton choix.

    Et le code pour le faire tient en quelques lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    static void Main(string[] args)
    {
       int[] generer = new int[5];
       HashSet<int> hashSet = new HashSet();
       Random r = new Random();
     
       while(hashSet.Count < generer.Length)
       {
          hashSet.Add(r.Next(0, 35);
       }
     
       generer = hashSet.ToArray();
    }

  6. #6
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2018
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Autre

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2018
    Messages : 12
    Points : 2
    Points
    2
    Par défaut
    merci pour votre réponse.On peut le faire avec deux méthodes aussi
    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
    static bool nombreunique(int[] tableau, int a)
            {
                foreach (int b in tableau)
                    if (a== b)
                        return true;
                return false;
            }
     
            static void generer(int[] tableau)
            {
                int a;
                Random r = new Random();
                for (int d = 0; d < tableau.Length; d++)
                {
                    do
                        a = r.Next(0, 53);
                    while (nombreunique(tableau, a));
                    tableau[i] = a;
                }
            }

  7. #7
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par vitaly24 Voir le message
    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
    static bool nombreunique(int[] tableau, int a)
            {
                foreach (int b in tableau)
                    if (a== b)
                        return true;
                return false;
            }
     
            static void generer(int[] tableau)
            {
                int a;
                Random r = new Random();
                for (int d = 0; d < tableau.Length; d++)
                {
                    do
                        a = r.Next(0, 53);
                    while (nombreunique(tableau, a));
                    tableau[i] = a;
                }
            }
    Méthode fonctionnelle, mais affreusement moche à cause de certains détails.

    Le plus gros, est le nom de la méthode nombreunique qui retourne true si le nombre n'est pas unique et false sinon. Bref, cela fait le contraire de ce que son nom suggère. Donc soit il faut changer le nom en un truc style NombrePasUnique, ou alors il faut inverser les conditions.

    Le second plus gros, serait d'avoir une convention de nommage. nombreunique est illisible. Il faut avoir une convention permettant de séparer les mots. En C#, classiquement, c'est l'usage d'une majuscule pour la première lettre de chaque mot. Ainsi NombreUnique est déjà beaucoup plus lisible.

    Enfin, concernant l'usage des accolades pour les expressions contenant une seule expression, il y a des débats. Mais en général, on accepte qu'il n'y ait pas d'accolades lorsque tout est sur une seule ligne. Dès lorsqu'il y en a plusieurs, il vaut mieux les utiliser, pour des questions de lisibilité et de maintenance du code. La boucle foreach est particulièrement difficile à lire. Et cela évite des erreurs bêtes en cas de modification de code.

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 13/03/2012, 10h32
  2. Réponses: 2
    Dernier message: 07/09/2009, 15h28
  3. Réponses: 14
    Dernier message: 14/02/2009, 07h56
  4. Nombre de répétitions dans une requête
    Par Superjuju92 dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 30/04/2008, 00h17
  5. nombre de répétitions dans chaînes de caractères
    Par jocarina dans le forum Langage SQL
    Réponses: 10
    Dernier message: 20/06/2005, 13h07

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