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 :

Transposer une matrice avec fonctions, pointeurs


Sujet :

C

  1. #1
    Membre confirmé
    Homme Profil pro
    Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php
    Inscrit en
    Mars 2010
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php

    Informations forums :
    Inscription : Mars 2010
    Messages : 48
    Par défaut Transposer une matrice avec fonctions, pointeurs
    Bonjour,

    Le code ci-dessous ne fonctionne pas comme attendu. Les valeurs retournées n'expriment pas quelque chose après la première permutation.

    Voici :

    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
     
     
    #include <stdio.h>
     
    #define LMAX 10
    #define CMAX 10
     
    void GetDim(int *FL, int *FC, int FLmax, int FCmax) ;
    void GetMat(int *FMat, int *FL, int *FC) ;
    void DisplayMat(int *FMat, int *FL, int *FC) ;
    int TranspoMat(int *FMat, int *FL, int *FC) ;
     
    int main(void)
    {
    	int Mat[LMAX][CMAX] ;
    	int Lig, Col ;
    	int ok ;
    	Lig = 11 ;
    	Col = 11 ;
    	ok = 0 ;
     
    	GetDim(&Lig, &Col, LMAX, CMAX) ;
    	printf("\n\nSAISIE DE MATRICE : \n") ;
    	GetMat(*Mat, &Lig, &Col) ;
     
    	printf("\nAFFICHAGE MATRICE : \n") ;
    	DisplayMat( (int *)Mat, &Lig, &Col) ;
     
    	if ( TranspoMat(*Mat, &Lig, &Col) )
    	{
    		printf("\nAFFICHAGE TRANSPO : \n") ;
    		DisplayMat( (int *)Mat, &Lig, &Col) ;
    	}
    	else
    		printf("\nLa matrice ne peut etre transposee.") ;
     
    	printf("\n\n") ;
    	return 0 ;
    }
     
    void GetDim(int *FL, int *FC, int FLmax, int FCmax)
    {
    	do
    	{
    		printf("\nEntrez le nbr de lignes : ") ;
    		scanf("%d", FL) ;
    	} while ( *FL < 0  ||  *FL > FLmax ) ;
     
    	do
    	{
    		printf("\nEntrez le nbr de colonnes : ") ;
    		scanf("%d", FC) ;
    	} while ( *FC < 0  ||  *FC > FCmax ) ;
    }
     
    void GetMat(int *FMat, int *FL, int *FC)
    {
    	int i, j ;
     
    	for ( i = 0  ;  i < *FL  ;  i++ )
    		for ( j = 0  ;  j < *FC  ;  j++ )
    		{
    			printf("Element[%d][%d] : ", i, j) ;
    			scanf("%d", (int *) FMat + i * *FC + j ) ;
    		}	
    }
     
    void DisplayMat(int *FMat, int *FL, int *FC)
    {
    	int i, j ;
    	printf("\n") ;
    	for ( i = 0  ;  i < *FL  ;  i++ )
    	{
    		for ( j = 0  ;  j < *FC  ;  j++ )
    			printf("%d", *(FMat + i * *FC + j) ) ;
    		printf("\n") ;
    	}
    }
     
    int TranspoMat(int *FMat, int *FL, int *FC)
    {
    	void PermutMat(int *x, int *y) ;
     
    	int i, j ;
    	int dmax ;
     
    	if ( *FL > CMAX  ||  *FC > LMAX )
    		return 0 ;
    	else
    	{
    		dmax = ( *FL > *FC ) ? *FL : *FC ;
    		for ( i = 0  ;  i < dmax  ;  i++ )
    			for ( j = 0  ;  j < i  ;  j++ )
    				PermutMat( FMat + i * CMAX + j, FMat + j * LMAX + i ) ;
    		PermutMat(FL, FC) ;
                    return 1 ;
    	}
     
    }
     
    void PermutMat(int *x, int *y)
    {
    	int aide ;
     
    	aide = *x ;
    	*x = *y ;
    	*y = aide ;	
    }

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Le code ci-dessous ne fonctionne pas comme attendu.
    Il faut d'abord préciser la configuration mémoire attendue, c'est à dire comment tu vas interpréter la position des données.

    Le tableau (qui sera traité plus loin comme à une dimension) est déclaré à deux dimensions :
    que je représente pour LMAX = 3 et CMAX = 5 de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    x x x x x
    x x x x x
    x x x x x
    Lors du remplissage de ce tableau par la fonction GetMat() pour des dimensions Lig = 2 et Col = 3, avec les valeurs 1,2,...,6 il devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        (1)                    (2)
    1 2 3 4 5  et non pas  1 2 3 x x x
    6 x x x x              4 5 6 x x x
    x x x x x              x x x x x x
    (Lig = 2 et Col = 3)
    Ce qui revient à dire que la structure 2D de Mat (par LMAX et CMAX) est sans objet, et qu'il suffit d'avoir
    La conséquence est également que LMAX et CMAX n'ont rien à faire dans la fonction de transposition puisqu'on attend alors pour être cohérent avec la configuration mémoire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
       (1)                     (2)
    1 4 2 5 3  et non pas  1 4 x x x
    6 x x x x              2 5 x x x
    x x x x x              3 6 x x x
    (Lig = 3 et Col = 2)
    Il faut choisir si on veut avoir la configuration (1) ou la configuration (2)

  3. #3
    Membre confirmé
    Homme Profil pro
    Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php
    Inscrit en
    Mars 2010
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php

    Informations forums :
    Inscription : Mars 2010
    Messages : 48
    Par défaut
    Bonjour Diogene,

    En fait, je comprends ta réponse en partie mais je n'arrive pas à trouver la solution.

    Ton code semble apporter une plus grande optimisation. J'ai juste modifier :

    par
    soit en définitive :
    j'aurais pu garder une constante pour exprimer 16 tout au travers du code dans un premier temps je veux juste que ça fonctionne...

    Après quoi, la piste n'est pas évidente à trouver.

    Peut-être ce sont les paramètres dans les fonctions... Je vais essayer d'écrire un code et de tout mettre dans main pour voir.

    En attendant, je pense que la solution se situe autour de ces lignes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    	{
    		dmax = ( *FL > *FC ) ? *FL : *FC ;
    		for ( i = 0  ;  i < dmax  ;  i++ )
    			for ( j = 0  ;  j < i  ;  j++ )
    				PermutMat( FMat + i * CMAX + j, FMat + j * LMAX + i ) ;
    		PermutMat(FL, FC) ;
    	}
    Voici le code de ce cours que j'ai compléter
    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    #include <stdio.h>
     
    int TranspoMat(int *FMat, int *FL, int LMAX, int *FC, int CMAX) ;
    void LireDim(int *FL, int LMax, int *FC, int CMax) ;
    void LireMat(int *FMat, int FL, int FC, int CMax) ;
    void EcrireMat(int *FMat, int FL, int FC, int CMax) ;
     
    int main(void)
    {
    	int M[16] ;
    	int L, C ;
     
    	LireDim(&L, 4, &C, 4) ;
    	LireMat( (int *)M, L, C, 4) ; /* L et C sont des valeurs */
    	printf("\n\nAFFICHAGE MATRICE : \n") ;
     
    	EcrireMat( (int *)M, L, C, 4) ; /* L et C sont des valeurs */
     
    	if ( TranspoMat( (int *)M, &L, 4, &C, 4) )
    	{
    		printf("\nMATRICE TRANSPOSEE : \n") ;
    		EcrireMat( (int *)M, L, C, 4) ;
    	}
    	else
    		printf("\aLa matrice ne peut etre transposee\n") ;
     
    }
     
    void LireDim(int *FL, int LMax, int *FC, int CMax)
    {	
    	printf("\n\nSAISIE DES DIMENSIONS : ") ;
    	do
    	{
    		printf("\nEntrez le nbr de lignes : ") ;
    		scanf("%d", FL) ;
    	} while ( *FL < 0  ||  *FL > LMax )  ;	
     
    	do
    	{
    		printf("\nEntrez le nbr de colones : ") ;
    		scanf("%d", FC) ;
    	} while ( *FC < 0  ||  *FC > LMax ) ;	
    }
     
    void LireMat(int *FMat, int FL, int FC, int CMax)
    {
    	int i, j ;
     
    	printf("\n") ;
    	for ( i = 0  ;  i < FL  ;  i++ )
    		for ( j = 0  ;  j < FC  ;  j++ )
    		{
    			printf("Element[%d][%d] : ", i, j) ;
    			scanf("%d", FMat + i * FC + j ) ;
    		}
    }
     
    void EcrireMat(int *FMat, int FL, int FC, int CMax)
    {
    	int i, j ;
     
    	printf("\n") ;
    	for ( i = 0  ;  i < FL  ;  i++ )
    	{
    		for ( j = 0  ;  j < FC  ;  j++ )
    			printf("%d", *(FMat + i * FC + j)  );
    		printf("\n") ;
    	}	
    }
     
    int TranspoMat(int *FMat, int *FL, int LMAX, int *FC, int CMAX)
    {
    	void PermutMat(int *a, int *b) ;
    	int i, j ;
     
    	int dmax ;
     
    	if ( *FL > CMAX  ||  *FC > LMAX )
    		return 0 ;
    	else
    	{
    		dmax = ( *FL > *FC) ? *FL : *FC ;
     
    		for ( i = 0  ;  i < dmax  ;  i++ )
    			for (  j = 0  ;  j < i  ;  j++ )
    				PermutMat(FMat + i * CMAX + j, FMat + j * CMAX + i) ;
     
    		PermutMat(FL, FC) ;
     
    		return 1 ;
    	}
    }
     
    void PermutMat(int *x, int *y)
    {
    	int aide ;
     
    	aide = *x ;
    	*x = *y ;
    	*y = aide ;	
    }
    Je ne sais pas si ça peut m'aider.

    Merci,

    Pascal

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Tu ne précise pas si tu optes pour le cas (1) ou le cas (2)

    * Dans un tableau à une dimension, (prenons 16 comme exemple) avec toujours la matrice 2x3, l'arrangement mémoire est dans le cas (1)

    (1) 1 2 3 4 5 6 x x x x x x x x x x
    Après transposition :
    (1) 1 4 2 5 3 6 x x x x x x x x x x

    Cette situation possède des avantages : On peut facilement allouer la mémoire suffisante et nécessaire à une matrice et la matrice transposée occupe la même place mémoire.

    -----------------------
    * Ce n'est pas le cas dans la situation (2) où on place la matrice dans un tableau conteneur 2D (même si on le construit comme un tableau 1D).
    Dans ce cas (en voyant le tableau de 16 comme un tableau 4x4) :

    (2) 1 2 3 x 4 5 6 x x x x x x x x x
    Après transposition :
    (2) 1 4 x x 2 5 x x 3 6 x x x x x x

    On ne peut pas utiliser ce tableau pour une matrice 2x5 ou 5x2 ou 3x5 ou 5x3 alors que cela ne pose pas de problèmes dans le cas (1). Par contre la transposition est assez simple (mais pour être toujours possible, il faut que le tableau conteneur soit carré).

    -----------------------
    * Hélas, dans le cas (1) la transposition n'est pas immédiate : il ne s'agit plus d'échanger simplement les valeurs dans le tableau comme dans le cas (2).
    Dans l'exemple, la position des données change de la façon suivante :

    0->0 ; 1->2 , 2->4 , 4->3 , 3->1 ; 6->6

    Deux points ne changent pas de position et les autres forment une boucle : la valeur en position 1 doit aller en position 2 dont la valeur doit aller en position 4 ...
    Ce n'est pas grave puisqu'il suffit de mettre la valeur en position 2 de coté et de placer à sa place la valeur en position 1; puis mettre la valeur en position 4 de coté pour mettre à la place la valeur précédemment sauvegardée et ainsi de suite. C'est simple à faire.

    Mais le cas présenté est simple, car il n'y a que des invariants et une seule boucle, mais le nombre de boucles (et leur taille) dépend du nombre de lignes et de colonnes, et il est très gênant de savoir quelles sont les valeurs qui n'ont pas été encore traitées à la fin d'une boucle.
    Je pense que cette transposition ne peut pas se faire simplement, dans le cas général, sur place et qu'il faut utiliser un tableau intermédiaire pour pouvoir traiter les points dans l'ordre :
    Si on utilise un tableau intermédiaire, le point en position n (n = 0..LC-1, L nombre de lignes, C le nombre de colonnes) dans le tableau original doit aller en m dans le tableau intermédiaire avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    - Pour n = 0 à LC-2 :
         Avec n = iC+j  (i =0.. L-1 ; j=0..C-1) (ce qui correspond à t[i][j] d'une matrice LxC) 
         alors m = jL+i (ce qui correspond à t[j][i] d'une matrice CxL)
         ce qui peut s'écrire : 
         m = (n-iC)L+i;  m = nL -i(LC-1) ; 
      soit :
      m = [[nL]]  avec [[x]] = x modulo (LC-1)
    
    - si n = LC-1 alors m = LC-1  : copier le dernier point de position LC-1
    
    - recopier le tableau intermédiaire dans le tableau d'origne.
    Pour être complet, voici d'où vient l'exercice :....
    Ce qui est amusant, ce sont les variations sur le thème !

  5. #5
    Membre confirmé
    Homme Profil pro
    Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php
    Inscrit en
    Mars 2010
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php

    Informations forums :
    Inscription : Mars 2010
    Messages : 48
    Par défaut
    Bonjour,

    Je trouve que ce sujet ne remporte pas un franc succès...

    Bref, j'ai pu solutionné après quelques recherche sur google :

    Le 1er code rencontré qui ne me renvoie pas les valeurs de la dernière ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    its simple 
    just do this swappping 
     
    for(i=0;i<m;i++) /*A*/ 
    for(j=0;j<i;j++) /*B*/ 
    { 
    x=a[i][j]; 
    a[i][j]=a[j][i]; 
    a[j][i]=x; 
    }
    Voici comment j'ai modifié :

    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
     
    /*Permutation : */
    for ( i = 0 ; i <= lig ; i++ ) /*A*/
    for ( j = 0 ; j <= i ; j++ ) /*B*/
    {
    int permut = MatA[i][j] ;
    MatA[i][j] = MatA[j][i] ;
    MatA[j][i] = permut ;
    }
    /*End of permutation */
    printf("\nDISPLAY MATRIX : \n") ;
    for ( i = 0 ; i < col ; i++ )
    {
    for ( j = 0 ; j < lig ; j++ )
    {
    printf("%d", MatA[i][j]) ;
    }
    printf("\n") ;
    }
    N'hésitez pas à me donner un avis sur le code lui-même...

    Merci

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Je pense qu'il te faut utiliser i < lig, mais j <= i.

    Pour les détails vous les cours de C et la FAQ C.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Réponses: 1
    Dernier message: 01/08/2010, 14h58
  2. Réponses: 5
    Dernier message: 25/01/2008, 11h15
  3. Calculer une matrice avec la méthode de EULER
    Par lematlabeur dans le forum MATLAB
    Réponses: 7
    Dernier message: 05/11/2007, 18h22
  4. Redimensionner une matrice avec "reshape"
    Par kmaniche dans le forum Images
    Réponses: 9
    Dernier message: 07/06/2006, 18h35
  5. une erreur avec les pointeur..
    Par lecyberax dans le forum C
    Réponses: 12
    Dernier message: 15/04/2006, 12h04

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