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 :

tableau à dimension variable


Sujet :

C++

  1. #1
    Membre du Club
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    53
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 53
    Points : 62
    Points
    62
    Par défaut tableau à dimension variable
    bonjour, j'essaye de faire un programme qui r'ealise la transformée d'ADAMAR,
    en fait c'est l'histoire d'une matrice carrée d'ordre 2 puissance n générée à l'aide d'une matrice carée d'ordre 2 puissance n-1.
    voila ma question: comment créer un tableau qui gere ça? j'ai essayé les pointeurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int **TabOrdN, **TabOrd2N, ord;
    for(int i=0;i<ord,i++)  for(int j=0;j<ord,j++)
    {
      TabOrd2N[i][j]=TabOrdN[i][j];     TabOrd2N[i+ord][j]=TabOrdN[i][j];
      TabOrd2N[i][j+ord]=TabOrdN[i][j];     TabOrd2N[i+ord][j+ord]= -TabOrdN[i][j];
    }
    mais ca me donne des resultats bizzares ( ╝╝+Ê♣◘○♠♥•,♦☺Ã╚╔┼█)

  2. #2
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2006
    Messages
    572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 572
    Points : 631
    Points
    631
    Par défaut
    t'as bien sur alloué toutes les cases de tes matrices ?

  3. #3
    Membre du Club
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    53
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 53
    Points : 62
    Points
    62
    Par défaut
    c'est justement ça le probleme combien de cases allouer puisque la taille sera variable? je voudrais faire quelque chose de récurrent

  4. #4
    Membre habitué Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Points : 177
    Points
    177
    Par défaut
    Salut,

    Je ne connais pas cet algoritme mais là déjà
    les 2 boucles for cote à cote c pas trop bon, de même
    que les déréférencement ??? des pointeurs.
    Je suis d'ailleur étonné que ça compile!
    Essaies plutôt un truc comme ça;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    int **TabOrdN, **TabOrd2N, ord;
    for(int i=0;i<ord,i++)  
    {
      TabOrd2N[i][j]=TabOrdN[i][j];     
      TabOrd2N[i][j+ord]=TabOrdN[i][j];    
     
      for(int j=0;j<ord,j++)
      {
       TabOrd2N[i+ord][j]=TabOrdN[i][j];
       TabOrd2N[i+ord][j+ord]= -TabOrdN[i][j];
      }
    }
    je ne sais pas si c'est l'algo que tu cherche mais c plus clair.
    Pour ce qui est des tableau redimensionnables je te conseillerais
    d'utiliser plutôt les vector de la stl, il y aura moins de risque d'erreurs.

  5. #5
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2006
    Messages
    572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 572
    Points : 631
    Points
    631
    Par défaut
    Citation Envoyé par tintin72
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    int **TabOrdN, **TabOrd2N, ord;
    for(int i=0;i<ord,i++)  
    {
      TabOrd2N[i][j]=TabOrdN[i][j];     
      TabOrd2N[i][j+ord]=TabOrdN[i][j];    
     
      for(int j=0;j<ord,j++)
      {
       TabOrd2N[i+ord][j]=TabOrdN[i][j];
       TabOrd2N[i+ord][j+ord]= -TabOrdN[i][j];
      }
    }
    vous faites un concours la c'est ça ?

  6. #6
    Membre du Club
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    53
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 53
    Points : 62
    Points
    62
    Par défaut
    je crois que ton algo fais la meme chose, c'est vrai que c'est plus clair, je vais essayer avec stl, merci..

  7. #7
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2006
    Messages
    572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 572
    Points : 631
    Points
    631
    Par défaut
    Citation Envoyé par akfp85
    je crois que ton algo fais la meme chose, c'est vrai que c'est plus clair, je vais essayer avec stl, merci..
    tu rigoles ? il n'a plus rien a voir, et surtout j est déclaré dans la deuxieme boucle.. C'est n'importe quoi ce qu'il a mis !

    enfin bon, un type matrice c'est quand meme pas compliqué a réaliser si ?
    si tu fais un int** TU DOIS L'ALLOUER, sinon ça saute.

    je te conseille de prendre des cours sur les bases des pointeurs avant de te lancer dans tes calculs de matrice

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256

  9. #9
    Membre du Club
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    53
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 53
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par Faiche
    si tu fais un int** TU DOIS L'ALLOUER, sinon ça saute.
    pour allouer il faut connaitre la taille seulement je ne connais pas la taille de la prochaine matrice puisque c'est récurrent...

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    donc tu veux réserver un espace mémoire sans connaît la taille de cet espace mémoire ?

  11. #11
    Membre du Club
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    53
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 53
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par olive_le_malin
    donc tu veux réserver un espace mémoire sans connaît la taille de cet espace mémoire ?
    ça ressemble un peu à ça, d'où la question suivante : ne peut on pas contourner cettre allocation?

  12. #12
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    tu peus toujours réallouer avec realloc

  13. #13
    Membre habitué Avatar de tintin72
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    663
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 663
    Points : 177
    Points
    177

  14. #14
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 632
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 632
    Points : 30 711
    Points
    30 711
    Par défaut
    Salut,

    Comme on est dans le forum C++, autant essayer de travailler... en C++...

    Le plus facile, c'est une fonction potentiellement récursive sous la forme de
    Le plus facile est de disposer d'une variable "globale" (ici, nomme taille)
    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
     
     
    int** Agrandit(int** depart)
    {
        int** tempo=new int*[taille+1];
        for(int i=0;i<taille;i++)
        {
             //allocation des colone, puis copie des éléments déjà connus
             tempo[i]=new int[taille+1]
             for(int j=0;j<taille;j++)
             {
                 tempo[i][j]=depart[i][j];
             }
             //déclaration de l'élément surnumeraire pour la ligne envisagée
             tempo[i][taille]= whatyouwant;
        }
        delete[] depart;
        ++taille;
        return tempo;
    }
    une autre solutions serait de passer la taille sous forme de parametre (en tant que reference,; pour qu'elle soit mise à jour automatiquement)

    Le prototype deviendrait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int** Agrandit(int** depart, size_t &taille);
    et elle serait appelée sous une forme ressemblant à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void mafonct
    {
    //le début du code de la fonction, dont la déclaration de la matrice et de sa
    //taille
        int** matrice;
        size_t taille;
    // <...>
       matrice=Agrandit(matrice, taille);
    //<...>
     
    }
    Ceci dit, comme je suis particulièrement attaché à l'utilisation des classes définies dans l'espace de nommage std, j'aurais meme t'endance à te conseiller l'utilisation de la classe vector, qui te facilitera grandement la tache...

    Comme il s'agit d'une matrice, il s'agira en réaliter de travailler avec un vector de vector du type qui t'intéresse...

    Ici, cela prendra la forme d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::vector<std::vector<int> > matrice;
    nota: remarque l'espace entre le premier > et le second: c'est pour éviter que le compilateur ne confonde avec l'operateur >> (de cin, par exemple)...

    La fonction qui permettra d'augmenter la taille de ta matrice prendra la forme de
    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
     
    void Agrandit(std::vector<std::vector<int> > & ref)
    {
        size_t taille;
        taille=ref.size();
        //redimentionnement de la matrice
        ref.resize(taille+1);
        //et des colones
        for(unsigned int i=0;i<ref.size();i++)
        {
            ref[i].resize(taille+1);
        }
        //définition des valeurs des colones manquantes
        for(unsigned int i=0;i<taille;i++)
        {
             //il y a une logique à suivre, ici, je décide juste
             //de mettre les valeurs à 15 pour l'exemple
             ref[i][taille]=15;
        }
        //définition des valeurs de la derniere ligne
        for(unsigned int i=0;i<=taille;i++)
        {
             //il y a une logique à suivre, ici, je décide juste
             //de mettre les valeurs à 30 pour l'exemple
             ref[taille][i]=30;
        }
    }
    et sera appelée sous la forme de
    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
     
    void mafonct()
    {
         //declaration de la matrice
        std::vector<std::vector<int> > matrice;
        matrice.resize(3);
        //allez, remplissons une matrice carree de 3*3, pour l'exemple
        for(unsigned int i=0;i<3;i++)
        {
            matrice[i].resize(3);
             for(unsigned int j=0;j<3;j++)
             {
                std::cout<<"introduisez l'element ["<<i<<"]["<<j<<"] de la matrice"
                         <<std::endl;
                std::cin>>matrice[i][j];
             }
     
        }
    // l'appel à la fonction
        Agrandit(matrice);
    }
    Il faudra juste penser à vider correctement la matrice avant de quitter...
    Cela se fera sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void VideMatrice(std::vector<std::vector<int> > &ref)
    {
        for(unsigned int i=0;i<ref.size();i++)
        {
     
            ref[i].clear();
        }
        ref.clear();
    }
    Edit: bien que le code précédent compilait, il fournissait des valeurs incohérentes, c'est la raison pour laquelle je l'ai édité... le code actuel fonctionne sans aucun problème...

  15. #15
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 282
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 282
    Points : 11 036
    Points
    11 036
    Par défaut
    Des réponses groupées...

    Citation Envoyé par akfp85
    en fait c'est l'histoire d'une matrice carrée d'ordre 2 puissance n générée à l'aide d'une matrice carée d'ordre 2 puissance n-1.
    voila ma question: comment créer un tableau qui gere ça? j
    boost.uBLAS, Blitz++, MTL, newMat, ... comme d'hab quoi.

    Pour les tableaux "rectangulaires" (pas matrices) -> boost.multi_array

    Pour les tableaux "irréguliers" -> std::vector<std::vector<T> >

    Pour les exercices -> cerveau - crayon - papier

    La FAQ C (qui en plus ne gère pas les cas d'erreurs) pour gérer ces structures, c'est moyen ... en C++.

    tu peux toujours réallouer avec realloc
    Attention, realloc() est vicieux, si ça foire, cela retourne 0. Et il ne faut pas oublier de libérer la mémoire en passant par des temporaires...


    Une fonction récursive est une fonction qui s'appelle...


    @ Koala. Ton premier code à-la-C présente plusieurs problèmes
    - il peut fuir si une erreur d'allocation survient en cours de redimensionnement
    - Il fuit car sa libération de la structure initiale est partielle.

  16. #16
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 632
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 632
    Points : 30 711
    Points
    30 711
    Par défaut
    Citation Envoyé par Luc Hermitte
    <snip>

    Une fonction récursive est une fonction qui s'appelle...
    Je voulais dire par là qu'elle pouvait tres facilement etre transformée en récursive si besoin était... j'aurais du le dire différemment (mea maxima culpa )

    Citation Envoyé par Luc Hermitte
    @ Koala. Ton premier code à-la-C présente plusieurs problèmes
    - il peut fuir si une erreur d'allocation survient en cours de redimensionnement
    - Il fuit car sa libération de la structure initiale est partielle.
    De fait... Je mets correction ici, pour laisser la pertinence à ta remarque (mais où avais-je la tete :oops )

    Par contre, en relisant le code (qui n'avait pas été testé à la compilation, je viens, en plus, de remarquer quelques erreurs de syntaxe que je corrige partout
    Code C++ : 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
    int** Agrandit(int** depart)
    {
        try
        {
            int** tempo=new int*[taille+1];
            for(int i=0;i<taille;i++)
            {
                 //allocation des colone, puis copie des éléments déjà connus
                 tempo[i]=new int[taille+1]
                 for(int j=0;j<taille;j++)
                 {
                     tempo[i][j]=depart[i][j];
                 }
                 //déclaration de l'élément surnumeraire pour la ligne envisagée
                 tempo[i][taille]= whatyouwant;
            }
        }
        //pour récupérer les différentes erreurs qui auraient pu survenir
        //(principalement les erreurs d'allocation)
        catch(...)
        {
             //l'affichage d'un message pourrait etre sympa, vraissemblablement
             // au travers de stc::cerr...
             // renvoie la matrice non modifiée
             return depart;
    //NOTA: typiquement, new renvoie une exception de type 
    // std::bad_alloc(), que l'on pourrait utiliser dans le catch 
    // (sous la forme decatch(std::bad_alloc &e) ) mais il faut alors penser à 
    //inclure le fichier d'entete <stdexcept>
        }
        // libération de la mémoire utilisée par la matrice de départ AVANT de
        // perdre l'adresse mémoire à laquelle elle commence
        for(int i=0;i<taille;i++)
        {
            //D'abord les colones
            int* supress=depart[i];
            delete[] suppress;
        }
        //puis les lignes
        delete[] depart;
        ++taille;
        return tempo;
    }

  17. #17
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Sauf que si c'est la première allocation qui produit une erreur, il faut pas libérer toutes les autres.
    Le plus simple est de loin d'utiliser std::vector<int>.

  18. #18
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Bonjour,

    et qu'est ce qu'en pense l'autur du message de toutes ces réponses ?

    Au départ j'avais suggéré des réponses en utilisant des fonctions C, car le code donné laissait sous-entendre un besoin de comprendre ce qu'était l'allocation de tableaux 2D, et les pointeurs ...
    avant de passer à l'utilisation des librairies C++, et des tableaux vector ...

    Mais bon ... peut être me suis-je trompé ?
    C'est clair que les vector seraient une bonne solution.

    @+

Discussions similaires

  1. tableau de dimension variable
    Par kapaty dans le forum C
    Réponses: 6
    Dernier message: 05/03/2010, 01h00
  2. Réponses: 11
    Dernier message: 11/06/2008, 19h05
  3. tableau à dimension variable
    Par bubuche87 dans le forum Débuter
    Réponses: 6
    Dernier message: 20/11/2007, 21h21
  4. tableau à dimension variable
    Par dnmfaw dans le forum Débuter
    Réponses: 5
    Dernier message: 10/09/2007, 19h09
  5. [débutant] un tableau de dimension variable selon l'objet qui le contient
    Par Epistocles dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 09/01/2007, 19h07

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