Problème matrice

Résolu/Fermé
Itil - 26 janv. 2013 à 13:35
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 - 28 janv. 2013 à 00:23
Bonjour,
mon but est de créer une matrice carrée N * N, avec N quelconque que je choisis, puis d'y sélectionner la valeur absolue maximale contenue dans le triangle supérieur (diagonale non comprise).
Voilà mon programme :

int main(int argc, char *argv[]){

int i,j,k,l,N,p,q;
double A[N][N], max;
printf("N = ?");
scanf("%d",&N);
for ( i = 0 ; i < N ; i++){
printf("Entrez les éléments de la %d ligne de la matrice A", i);
for ( j = 0 ; j < N ; j++){
scanf("%lf",&A[i][j]);}}

for ( k = 0 ; k < N ; k++){
for ( l = k + 1 ; l < N ; l++){
max = fabs(A[0][1]);
if (fabs(A[k][l]) > max){
max = fabs(A[k][l]);
p = k;
q = l;}
else{ max = fabs(A[0][1]);
p = 0;
q = 1;}
}
}
printf("p=%d, q=%d",p,q);
printf("max=%lf\n",max);

system("PAUSE");
return 0;
}

Le problème est qu'il ne sélectionne pas toutes les valeurs.
Par exemple, pour la matrice

1 2 5
2 1 4
7 2 7

il devrait me dire que le maximum est 5, or il me dit que c'est 4.

Merci de votre aide

7 réponses

mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 811
26 janv. 2013 à 14:07
Comment se fait-il que tu es 4 boucles for imbriquées ?

De deux choses l'une :
- soit tu calcules le max au moment de la saisie (et ça tient en deux boucles for, il suffit juste à chaque valeur saisie de voir si on est dans le triangle ou pas et mettre à jour max)
- soit tu fais au début deux boucles for pour initialiser la matrice, puis en ensuite plus loin deux boucles for qui parcourent le triangle supérieur

La première méthode est plus efficace mais ne permet de chercher le max que lors de la saisie. La seconde prépare le terrain pour écrire une fonction qui cherche le max dans une matrice quelconque.

Évite d'utiliser system("PAUSE") qui rend ton programme dépendant du system (ici windows), tu peux par exemple le remplacer par getchar().

Bonne chance
0
Je n'ai pas 4 boucles imbriquées, car les 2 premières se terminent par }}

"- soit tu fais au début deux boucles for pour initialiser la matrice, puis en ensuite plus loin deux boucles for qui parcourent le triangle supérieur"

c'est ce que j'ai fait.
Le problème est justement le parcours des valeurs par la boucle.
0
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 811
26 janv. 2013 à 21:02
Au temps pour moi, je n'avais pas vu les accolades, je me suis fait avoir avec l'indentation et le fait que tu aies utilisé 4 variables au lieu de 2. En effet peux complètement réutiliser dans tes boucles 3 et 4 les variables i et j qui ne sont plus utilisées. Pour l'indentation, je te conseille par la suite de passer à la ligne après une accolade ouvrante, et passer à la ligne devant et après une accolade fermante.

Bon déjà, l'allocation ne va pas du tout. Tu ne peux pas écrire "int A[N][N]" car le compilateur ne sait pas quelle valeur va prendre N sauf si sa valeur a été au préalable initialisée (par un #define ou un const unsigned par exemple), ce qui n'est pas le cas ici.

Il y a deux solutions :
- soit tu suralloues A (par exemple A[99][99]) mais c'est pas top
- soit fais une allocation dynamique (cf malloc) une fois la valeur de N saisie par l'utilisateur.

Un exemple de la seconde approche est donné ici :
https://forums.commentcamarche.net/forum/affich-26986215-probleme-avec-les-matrices#3

Ensuite au niveau de l'algo, avant de parler de A[0][1] dans le cas général il faut s'assurer que la case existe (ie N >= 2) sinon tu vas avoir une erreur mémoire ou un résultat faux dans le cas général.

Autre souci, ton max il faut l'initialiser en dehors des boucles (de même que p et q que tu vas initialisé respectivement à 0 et 1), et ensuite mettre à jour ces trois variables au cours de ton parcours.

Du coup ça ressemble plus à ça :

#include <stdio.h>
#include <math.h>

int main() {
    int i, j, n, p, q; 
    const unsigned N = 10;
    double A[N][N], max; 
    printf("n = ? ");
    scanf("%d", &n); 
    for (i = 0 ;i < n ;i++) { 
        printf("Entrez les éléments de la %d ligne de la matrice A\n", i); 
        for (j = 0 ;j < n ;j++) { 
            scanf("%jf", &A[i][j]);
        }
    } 

    if (n >= 2) {
        max = fabs(A[0][1]); 
        p = 0; 
        q = 1;
        for (i = 0 ;i < n ;i++) { 
            for (j = i + 1 ;j < n ;j++) { 
                max = fabs(A[0][1]); 
                if (fabs(A[i][j]) > max) { 
                    max = fabs(A[i][j]); 
                    p = i; 
                    q = j;
                }
            } 
        }
        printf("p = %d\nq = %d\nmax = %lf\n", p, q, max);
    }

    return 0; 
}


Bonne chance
0
merci pour la réponse.

"Ensuite au niveau de l'algo, avant de parler de A[0][1] dans le cas général il faut s'assurer que la case existe (ie N >= 2) sinon tu vas avoir une erreur mémoire ou un résultat faux dans le cas général. "

C'est vrai, et je l'ai rajouté...
Mais comme j'utilise des matrices carrées au moins 3 x 3, j'avais oublié cette condition.
Sinon j'ai pas mis "int A[N][N] " mais bien "double A[N][N] "

J'ai tout essayé, ça ne marche pas.
Ton programme ne marche pas non plus.
Déjà il faut remplaçer %jf par %lf (ligne 13)
Il ignore toujours la valeur située en haut à droite de la matrice !!!
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 811
Modifié par mamiemando le 27/01/2013 à 13:33
Tu as raison, il y a une erreur dans le code précédent.

Je suis reparti du code que tu avais proposé et j'ai oublié de corriger l'initialisation du max, qui doit être faite en dehors des boucles for. Sinon à chaque itération dans l'exemple ci-dessous tu le réinitialise à 2 (et donc la valeur trouvée est la dernière dans ton parcours qui est supérieure à 2, ici 5).

#include <stdio.h> 
#include <math.h> 

int main() { 
    unsigned i, j, n, p, q; 
    double max; 
    double A[3][3] = { 
        { 1, 2, 6}, 
        { 3, 4, 5}, 
        { 1, 2, 3} 
    }; 
    n = 3; 

    for (i = 0 ;i < n ;i++) { 
        for (j = 0 ;j < n ;j++) { 
            printf("%lf\t", A[i][j]); 
        } 
        printf("\n"); 
    } 

    if (n >= 2) { 
        max = fabs(A[0][1]); 
        p = 0; 
        q = 1; 
        max = fabs(A[0][1]); 
        for (i = 0 ;i < n ;i++) { 
            for (j = i + 1 ;j < n ;j++) { 
                if (fabs(A[i][j]) > max) { 
                    max = fabs(A[i][j]); 
                    p = i; 
                    q = j; 
                } 
            } 
        } 
        printf("p = %d\nq = %d\nmax = %lf\n", p, q, max); 
    } 

    return 0; 
}


Sortie :

1.000000        2.000000        6.000000 
3.000000        4.000000        5.000000 
1.000000        2.000000        3.000000 
p = 0 
q = 2 
max = 6.000000 


Bonne chance
0
Merci ça marche !
J'ai simplement enlevé :

else{ max = fabs(A[0][1]);
p = 0;
q = 1;}
et j'ai sorti le max des boucles for.
Merci pour la réactivité de tes réponses.
0
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 811
28 janv. 2013 à 00:23
Pas de soucis, bonne continuation !
0