4SI
Sommaire
- Déclaration et matrice de l’exemple
- Saisie, remplissage et affichage
- Les zones d’une matrice
- Calculs : sommes, maximum, minimum, occurrences
- Recherche d’un élément
- Vérifications de propriétés
- Transformations : diagonales, transposée, lignes, tris
- Matrice et tableau
- De la matrice vers un fichier texte
- D’un fichier texte vers une matrice
- Matrice et fichier de données
- Les erreurs les plus fréquentes
- Retenons
1. Déclaration et matrice de l’exemple
1.1 Règles communes à tous les modules
- Chaque module est autonome : il traite une seule tâche.
NLest le nombre de lignes etNCle nombre de colonnes ; une matrice carrée aNlignes etNcolonnes.- Les lignes sont numérotées de
0àNL - 1, les colonnes de0àNC - 1. La case de la ligneiet de la colonnejse noteM[i, j]. - Un paramètre
NomFichest une chaîne de caractères qui contient l’emplacement et le nom physique du fichier. Le module ouvre et ferme lui-même le fichier.
1.2 Les types utilisés
TDNT
| Nouveau type |
|---|
Mat = Tableau de 20 lignes * 20 colonnes d'entiers |
MatC = Tableau de 20 lignes * 50 colonnes de caractères |
Tab = Tableau de 400 entiers |
FEnt = Fichier d'entiers |
Tab peut contenir les 20 × 20 éléments d’une matrice de type Mat.
En Python
from numpy import array
M = array([[0] * 20] * 20) # Mat : 20 lignes * 20 colonnes d'entiers
MC = array([[''] * 50] * 20, dtype='U1') # MatC : 20 lignes * 50 colonnes de caractères
T = array([0] * 400) # Tab : 400 entiers
Remarque importante. Sans
dtype, une matrice de chaînes ne garde que le premier caractère de chaque case. Pour une matrice de caractères,dtype='U1'suffit ; pour des chaînes, préciser une longueur :dtype='U20'.
1.3 La matrice de l’exemple
Tous les résultats donnés dans ce résumé ont été obtenus sur la même matrice carrée M de 4 lignes et 4 colonnes :
| 0 | 1 | 2 | 3 | |
|---|---|---|---|---|
| 0 | 5 | 2 | 9 | 1 |
| 1 | 7 | 3 | 2 | 8 |
| 2 | 4 | 6 | 0 | 3 |
| 3 | 2 | 9 | 5 | 7 |
Le maximum, 9, y figure deux fois, en M[0, 2] et en M[3, 1], et le minimum, 0, une seule fois, en M[2, 2] : c’est ce qui permet de voir, dans les modules de position, laquelle des deux occurrences est retournée.
2. Saisie, remplissage et affichage
2.1 Saisir les dimensions
Procédure qui saisit NL et NC, deux entiers de l’intervalle [2, 20].
Procédure Saisir_Dim (@NL, @NC : Entier)
DEBUT
Répéter
Écrire("Nombre de lignes : ")
Lire(NL)
Jusqu'à (2 ≤ NL) Et (NL ≤ 20)
Répéter
Écrire("Nombre de colonnes : ")
Lire(NC)
Jusqu'à (2 ≤ NC) Et (NC ≤ 20)
FIN
Pas de TDOL : la procédure n’a ni variable locale, ni module appelé.
En Python
def Saisir_Dim():
global NL, NC
NL = int(input("Nombre de lignes : "))
while not (2 <= NL <= 20):
NL = int(input("Nombre de lignes : "))
NC = int(input("Nombre de colonnes : "))
while not (2 <= NC <= 20):
NC = int(input("Nombre de colonnes : "))
En détail
La procédure produit deux résultats : en Python, ils passent par global, jamais par return NL, NC. Pour une matrice carrée, une seule saisie suffit : N.
2.2 Remplir une matrice par saisie contrôlée
Procédure qui remplit M par des entiers strictement positifs.
Procédure Remplir (@M : Mat, NL, NC : Entier)
DEBUT
Pour i de 0 à NL - 1 Faire
Pour j de 0 à NC - 1 Faire
Répéter
Écrire("M[", i, ",", j, "] : ")
Lire(M[i, j])
Jusqu'à M[i, j] > 0
Fin Pour
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j | Entier |
En Python
def Remplir(M, NL, NC):
for i in range(NL):
for j in range(NC):
M[i, j] = int(input("M[" + str(i) + "," + str(j) + "] : "))
while not (M[i, j] > 0):
M[i, j] = int(input("M[" + str(i) + "," + str(j) + "] : "))
Seule la condition de Jusqu'à change d’un énoncé à l’autre : M[i, j] ∈ [0..20] pour une note, Premier(M[i, j]) pour un nombre premier, etc.
2.3 Remplir une matrice par des valeurs aléatoires
Procédure RemplirBinaire(M, NL, NC) qui remplit M par des valeurs aléatoires binaires, 0 ou 1.
Procédure RemplirBinaire (@M : Mat, NL, NC : Entier)
DEBUT
Pour i de 0 à NL - 1 Faire
Pour j de 0 à NC - 1 Faire
M[i, j] ← Aléa(0, 1)
Fin Pour
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j | Entier |
En Python
from random import randint
def RemplirBinaire(M, NL, NC):
for i in range(NL):
for j in range(NC):
M[i, j] = randint(0, 1)
Pour d’autres bornes, seul l’intervalle change : Aléa(10, 99) donne des entiers de deux chiffres.
2.4 Remplir une matrice par des valeurs distinctes
Procédure RemplirDistinct(M, NL, NC) qui remplit M par des entiers distincts saisis par l’utilisateur.
On lit directement dans M[i, j], puis on vérifie que cette valeur n’apparaît dans aucune des cases déjà remplies : toutes les lignes avant la ligne i, et, sur la ligne i, les colonnes avant j.
Procédure RemplirDistinct (@M : Mat, NL, NC : Entier)
DEBUT
Pour i de 0 à NL - 1 Faire
Pour j de 0 à NC - 1 Faire
Répéter
Écrire("M[", i, ",", j, "] : ")
Lire(M[i, j])
Jusqu'à Non(Deja_Vue(M, NC, i, j))
Fin Pour
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j | Entier |
Deja_Vue | Fonction |
Fonction Deja_Vue (M : Mat, NC, L, C : Entier) : Booléen
DEBUT
trouve ← Faux
i ← 0
Tant que (i ≤ L) Et Non(trouve) Faire
j ← 0
Tant que (((i < L) Et (j < NC)) Ou ((i = L) Et (j < C))) Et Non(trouve) Faire
Si M[i, j] = M[L, C] Alors
trouve ← Vrai
Sinon
j ← j + 1
FinSi
Fin Tant que
i ← i + 1
Fin Tant que
Retourner trouve
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j | Entier |
trouve | Booléen |
En Python
def Deja_Vue(M, NC, L, C):
trouve = False
i = 0
while (i <= L) and not trouve:
j = 0
while ((i < L and j < NC) or (i == L and j < C)) and not trouve:
if M[i, j] == M[L, C]:
trouve = True
else:
j = j + 1
i = i + 1
return trouve
def RemplirDistinct(M, NL, NC):
for i in range(NL):
for j in range(NC):
M[i, j] = int(input("M[" + str(i) + "," + str(j) + "] : "))
while Deja_Vue(M, NC, i, j):
M[i, j] = int(input("M[" + str(i) + "," + str(j) + "] : "))
Exemple vérifié. Pour une matrice de 3 lignes et 2 colonnes, les saisies 5, 5, 2, 9, 2, 5, 1, 7, 7, 3 donnent la matrice 5 2 / 9 1 / 7 3 : les valeurs refusées sont le deuxième 5, puis 2 et 5, puis le deuxième 7.
Remarque importante. Lire directement dans
M[i, j]est sûr : la zone parcourue parDeja_Vues’arrête avant la case(L, C), la valeur saisie ne se compare donc jamais à elle-même. Pour la première case,(0, 0), la zone est vide etDeja_Vueretourne Faux : aucun test(i = 0) Et (j = 0)n’est nécessaire.
En détail
La condition de la boucle intérieure décrit la zone déjà remplie : sur les lignes i < L, toutes les colonnes ; sur la ligne L, les colonnes j < C seulement. Comparée à une recherche directe sur 20 000 matrices tirées au hasard, cette fonction n’a donné aucun écart.
2.5 Afficher une matrice
Procédure qui affiche M ligne par ligne, les éléments d’une même ligne étant séparés par un espace.
Procédure Afficher (M : Mat, NL, NC : Entier)
DEBUT
Pour i de 0 à NL - 1 Faire
Pour j de 0 à NC - 1 Faire
Écrire(M[i, j], " ")
Fin Pour
Écrire_nl()
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j | Entier |
En Python
def Afficher(M, NL, NC):
for i in range(NL):
for j in range(NC):
print(M[i, j], end=" ")
print()
En détail
Le passage à la ligne se place après la boucle sur j : un Écrire_nl() dans la boucle afficherait un élément par ligne. Python n’affiche jamais print(M) : on affiche élément par élément.
3. Les zones d’une matrice
3.1 Les conditions sur les indices
La case courante étant M[i, j] :
| Zone | Condition sur (i, j) |
|---|---|
| Diagonale principale | i = j |
| Diagonale secondaire | i + j = N - 1, matrice carrée |
| Au-dessus de la diagonale principale | j > i |
| Au-dessous de la diagonale principale | j < i |
| Au-dessus de la diagonale secondaire | i + j < N - 1 |
| Au-dessous de la diagonale secondaire | i + j > N - 1 |
| Bordure | (i = 0) Ou (i = NL - 1) Ou (j = 0) Ou (j = NC - 1) |
Les deux diagonales passant par M[L, C] | (i + j = L + C) Ou (i - j = L - C), ou encore Abs(i - L) = Abs(j - C) |
3.2 Parcourir une zone sans tester toutes les cases
Une condition de zone peut se placer dans un Si, à l’intérieur du parcours complet. Mais il est souvent plus simple de parcourir directement la zone, en choisissant les bornes des boucles :
| Zone parcourue | Boucles |
|---|---|
| Diagonale principale | Pour i de 0 à N - 1 → M[i, i] |
| Diagonale secondaire | Pour i de 0 à N - 1 → M[i, N - 1 - i] |
| Au-dessus de la diagonale principale | Pour i de 0 à N - 2 puis Pour j de i + 1 à N - 1 |
| Au-dessous de la diagonale principale | Pour i de 1 à N - 1 puis Pour j de 0 à i - 1 |
| Au-dessus de la diagonale secondaire | Pour i de 0 à N - 2 puis Pour j de 0 à N - 2 - i |
Sur la matrice M : la diagonale principale 5, 3, 0, 7 a pour somme 15, la diagonale secondaire 1, 2, 6, 2 a pour somme 11.
En détail
Les modules du paragraphe 7.1, qui échangent les deux moitiés d’une matrice autour d’une diagonale, parcourent exactement une de ces zones : celle au-dessous de la diagonale principale, et celle au-dessus de la diagonale secondaire.
4. Calculs : sommes, maximum, minimum, occurrences
4.1 SommeMatrice
Fonction SommeMatrice(M, NL, NC) qui calcule la somme de tous les éléments de M.
Fonction SommeMatrice (M : Mat, NL, NC : Entier) : Entier
DEBUT
s ← 0
Pour i de 0 à NL - 1 Faire
Pour j de 0 à NC - 1 Faire
s ← s + M[i, j]
Fin Pour
Fin Pour
Retourner s
FIN
TDOL
| Objet | Type / Nature |
|---|---|
s, i, j | Entier |
En Python
def SommeMatrice(M, NL, NC):
s = 0
for i in range(NL):
for j in range(NC):
s = s + M[i, j]
return s
Sur la matrice M : 73.
4.2 SommeLigne et SommeColonne
Fonction SommeLigne(M, NC, NUML) qui calcule la somme des éléments de la ligne NUML, et fonction SommeColonne(M, NL, NUMC) qui calcule celle des éléments de la colonne NUMC.
Fonction SommeLigne (M : Mat, NC, NUML : Entier) : Entier
DEBUT
s ← 0
Pour j de 0 à NC - 1 Faire
s ← s + M[NUML, j]
Fin Pour
Retourner s
FIN
TDOL
| Objet | Type / Nature |
|---|---|
s, j | Entier |
Fonction SommeColonne (M : Mat, NL, NUMC : Entier) : Entier
DEBUT
s ← 0
Pour i de 0 à NL - 1 Faire
s ← s + M[i, NUMC]
Fin Pour
Retourner s
FIN
TDOL
| Objet | Type / Nature |
|---|---|
s, i | Entier |
En Python
def SommeLigne(M, NC, NUML):
s = 0
for j in range(NC):
s = s + M[NUML, j]
return s
def SommeColonne(M, NL, NUMC):
s = 0
for i in range(NL):
s = s + M[i, NUMC]
return s
Sur la matrice M :
| 0 | 1 | 2 | 3 | |
|---|---|---|---|---|
| Somme de la ligne | 17 | 20 | 13 | 23 |
| Somme de la colonne | 18 | 20 | 16 | 19 |
Remarque importante. Pour une ligne, l’indice de ligne est fixe et seul
jvarie ; pour une colonne, c’est l’inverse. Une seule boucle suffit : la fonction n’a besoin que deNCpour une ligne, deNLpour une colonne.
4.3 SommeDiagonales
Fonction SommeDiagonales(M, N) qui calcule la somme des éléments des deux diagonales d’une matrice carrée.
Fonction SommeDiagonales (M : Mat, N : Entier) : Entier
DEBUT
s ← 0
Pour i de 0 à N - 1 Faire
s ← s + M[i, i] + M[i, N - i - 1]
Fin Pour
Si N Mod 2 = 1 Alors
s ← s - M[N Div 2, N Div 2]
FinSi
Retourner s
FIN
TDOL
| Objet | Type / Nature |
|---|---|
s, i | Entier |
En Python
def SommeDiagonales(M, N):
s = 0
for i in range(N):
s = s + M[i, i] + M[i, N - i - 1]
if N % 2 == 1:
s = s - M[N // 2, N // 2]
return s
Sur la matrice M : 15 + 11 = 26.
Remarque importante. Lorsque
Nest impair, les deux diagonales se croisent sur la case centraleM[N Div 2, N Div 2], ajoutée deux fois par la boucle : on la retranche une fois. LorsqueNest pair, elles n’ont aucune case commune. Pour la matrice1 2 3 / 4 5 6 / 7 8 9, la fonction retourne 25 ; sans la correction, elle retournerait 30.
4.4 MaximumMatrice
Fonction MaximumMatrice(M, NL, NC) qui retourne le plus grand élément de M.
Fonction MaximumMatrice (M : Mat, NL, NC : Entier) : Entier
DEBUT
max ← M[0, 0]
Pour i de 0 à NL - 1 Faire
Pour j de 0 à NC - 1 Faire
Si M[i, j] > max Alors
max ← M[i, j]
FinSi
Fin Pour
Fin Pour
Retourner max
FIN
TDOL
| Objet | Type / Nature |
|---|---|
max, i, j | Entier |
En Python
def MaximumMatrice(M, NL, NC):
Max = M[0, 0]
for i in range(NL):
for j in range(NC):
if M[i, j] > Max:
Max = M[i, j]
return Max
Sur la matrice M : 9.
Remarque importante. On initialise avec un élément de la matrice,
M[0, 0], jamais avec 0 : sur une matrice dont tous les éléments sont négatifs, une initialisation à 0 retournerait 0, qui n’est pas dans la matrice.
En détail
La boucle repasse sur M[0, 0], déjà utilisé pour l’initialisation. C’est sans effet sur le résultat, puisque M[0, 0] > M[0, 0] est faux, et cela évite un traitement à part de la ligne 0.
4.5 PositionMinimum
Procédure PositionMinimum(M, NL, NC, LMin, CMin) qui détermine la ligne LMin et la colonne CMin du plus petit élément de M. Si le minimum apparaît plusieurs fois, on retient la première case rencontrée.
La procédure produit deux résultats : c’est une procédure, et LMin, CMin sont passés par référence.
Méthode 1 : on garde la valeur du minimum
Procédure PositionMinimum (M : Mat, NL, NC : Entier, @LMin, @CMin : Entier)
DEBUT
min ← M[0, 0]
LMin ← 0
CMin ← 0
Pour i de 0 à NL - 1 Faire
Pour j de 0 à NC - 1 Faire
Si M[i, j] < min Alors
min ← M[i, j]
LMin ← i
CMin ← j
FinSi
Fin Pour
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
min, i, j | Entier |
Méthode 2 : on garde seulement la position
Procédure PositionMinimum (M : Mat, NL, NC : Entier, @LMin, @CMin : Entier)
DEBUT
LMin ← 0
CMin ← 0
Pour i de 0 à NL - 1 Faire
Pour j de 0 à NC - 1 Faire
Si M[i, j] < M[LMin, CMin] Alors
LMin ← i
CMin ← j
FinSi
Fin Pour
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j | Entier |
En Python
def PositionMinimum(M, NL, NC):
global LMin, CMin
LMin = 0
CMin = 0
for i in range(NL):
for j in range(NC):
if M[i, j] < M[LMin, CMin]:
LMin = i
CMin = j
Sur la matrice M : LMin = 2, CMin = 2. La valeur du minimum s’obtient ensuite par M[LMin, CMin], soit 0.
Remarque importante. C’est la comparaison stricte
<qui garantit la première occurrence. Avec≤, on retiendrait la dernière : la recherche de la position du maximum avec≥donne(3, 1)sur la matriceM, au lieu de(0, 2).
4.6 MaximumLigne et MaximumColonne
Fonction MaximumLigne(M, NC, NUML) qui retourne le maximum de la ligne NUML, et fonction MaximumColonne(M, NL, NUMC) qui retourne le maximum de la colonne NUMC.
Fonction MaximumLigne (M : Mat, NC, NUML : Entier) : Entier
DEBUT
max ← M[NUML, 0]
Pour j de 1 à NC - 1 Faire
Si M[NUML, j] > max Alors
max ← M[NUML, j]
FinSi
Fin Pour
Retourner max
FIN
TDOL
| Objet | Type / Nature |
|---|---|
max, j | Entier |
Fonction MaximumColonne (M : Mat, NL, NUMC : Entier) : Entier
DEBUT
max ← M[0, NUMC]
Pour i de 1 à NL - 1 Faire
Si M[i, NUMC] > max Alors
max ← M[i, NUMC]
FinSi
Fin Pour
Retourner max
FIN
TDOL
| Objet | Type / Nature |
|---|---|
max, i | Entier |
En Python
def MaximumLigne(M, NC, NUML):
Max = M[NUML, 0]
for j in range(1, NC):
if M[NUML, j] > Max:
Max = M[NUML, j]
return Max
def MaximumColonne(M, NL, NUMC):
Max = M[0, NUMC]
for i in range(1, NL):
if M[i, NUMC] > Max:
Max = M[i, NUMC]
return Max
Sur la matrice M :
| 0 | 1 | 2 | 3 | |
|---|---|---|---|---|
| Maximum de la ligne | 9 | 8 | 6 | 9 |
| Maximum de la colonne | 7 | 9 | 9 | 8 |
Le minimum d’une ligne ou d’une colonne s’écrit de la même façon, en inversant la comparaison.
4.7 Nb_Occurrences
Fonction Nb_Occurrences(M, NL, NC, X) qui retourne le nombre d’apparitions de l’entier X dans M.
Fonction Nb_Occurrences (M : Mat, NL, NC, X : Entier) : Entier
DEBUT
nb ← 0
Pour i de 0 à NL - 1 Faire
Pour j de 0 à NC - 1 Faire
Si M[i, j] = X Alors
nb ← nb + 1
FinSi
Fin Pour
Fin Pour
Retourner nb
FIN
TDOL
| Objet | Type / Nature |
|---|---|
nb, i, j | Entier |
En Python
def Nb_Occurrences(M, NL, NC, X):
nb = 0
for i in range(NL):
for j in range(NC):
if M[i, j] == X:
nb = nb + 1
return nb
Sur la matrice M : Nb_Occurrences(M, 4, 4, 9) retourne 2, Nb_Occurrences(M, 4, 4, 2) retourne 3.
5. Recherche d’un élément
5.1 RechercheLigne
Fonction RechercheLigne(M, NC, NUML, X) qui vérifie si l’entier X figure dans la ligne NUML.
Méthode 1 : avec un drapeau
Fonction RechercheLigne (M : Mat, NC, NUML, X : Entier) : Booléen
DEBUT
trouve ← Faux
j ← 0
Tant que (j < NC) Et Non(trouve) Faire
Si M[NUML, j] = X Alors
trouve ← Vrai
Sinon
j ← j + 1
FinSi
Fin Tant que
Retourner trouve
FIN
TDOL
| Objet | Type / Nature |
|---|---|
j | Entier |
trouve | Booléen |
Méthode 2 : la condition dans la boucle
Fonction RechercheLigne (M : Mat, NC, NUML, X : Entier) : Booléen
DEBUT
j ← 0
Tant que (j < NC) Et (M[NUML, j] ≠ X) Faire
j ← j + 1
Fin Tant que
Retourner j < NC
FIN
TDOL
| Objet | Type / Nature |
|---|---|
j | Entier |
En Python
def RechercheLigne(M, NC, NUML, X):
j = 0
while (j < NC) and (M[NUML, j] != X):
j = j + 1
return j < NC
Sur la matrice M : RechercheLigne(M, 4, 1, 8) retourne Vrai, RechercheLigne(M, 4, 1, 9) retourne Faux.
5.2 RechercheMatrice
Fonction RechercheMatrice(M, NL, NC, X) qui vérifie si l’entier X figure dans M. La recherche s’arrête dès que X est trouvé.
Fonction RechercheMatrice (M : Mat, NL, NC, X : Entier) : Booléen
DEBUT
trouve ← Faux
i ← 0
Tant que (i < NL) Et Non(trouve) Faire
j ← 0
Tant que (j < NC) Et Non(trouve) Faire
Si M[i, j] = X Alors
trouve ← Vrai
Sinon
j ← j + 1
FinSi
Fin Tant que
i ← i + 1
Fin Tant que
Retourner trouve
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j | Entier |
trouve | Booléen |
En Python
def RechercheMatrice(M, NL, NC, X):
trouve = False
i = 0
while (i < NL) and not trouve:
j = 0
while (j < NC) and not trouve:
if M[i, j] == X:
trouve = True
else:
j = j + 1
i = i + 1
return trouve
Sur la matrice M : la recherche de 6 retourne Vrai, celle de 10 retourne Faux.
En détail
Les deux boucles portent la condition Non(trouve) : la boucle intérieure s’arrête sur la case trouvée, la boucle extérieure ne commence pas de nouvelle ligne. Avec deux boucles Pour, la fonction donnerait le même résultat, mais parcourrait toujours toute la matrice.
5.3 PositionEntierMatrice
Procédure PositionEntierMatrice(M, NL, NC, X, LX, CX) qui détermine la ligne LX et la colonne CX de la première apparition de X dans M. Si X est absent, LX et CX reçoivent -1.
Procédure PositionEntierMatrice (M : Mat, NL, NC, X : Entier, @LX, @CX : Entier)
DEBUT
LX ← -1
CX ← -1
i ← 0
Tant que (i < NL) Et (LX = -1) Faire
j ← 0
Tant que (j < NC) Et (LX = -1) Faire
Si M[i, j] = X Alors
LX ← i
CX ← j
Sinon
j ← j + 1
FinSi
Fin Tant que
i ← i + 1
Fin Tant que
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j | Entier |
En Python
def PositionEntierMatrice(M, NL, NC, X):
global LX, CX
LX = -1
CX = -1
i = 0
while (i < NL) and (LX == -1):
j = 0
while (j < NC) and (LX == -1):
if M[i, j] == X:
LX = i
CX = j
else:
j = j + 1
i = i + 1
Sur la matrice M : pour X = 9, LX = 0 et CX = 2 ; pour X = 10, LX = CX = -1.
En détail
La valeur -1 ne peut pas être un indice : elle joue ici le rôle du drapeau. Tant que LX vaut -1, X n’a pas été trouvé.
6. Vérifications de propriétés
Une vérification « tous les éléments respectent une propriété » s’arrête dès le premier contre-exemple : elle s’écrit avec Tant que. Deux boucles Pour donneraient le bon résultat, mais parcourraient toute la matrice même après un contre-exemple.
6.1 Symetrique
Une matrice carrée est symétrique lorsque M[i, j] = M[j, i] pour toutes les cases. Il suffit de comparer chaque case située au-dessous de la diagonale principale à sa symétrique.
Fonction Symetrique (M : Mat, N : Entier) : Booléen
DEBUT
ok ← Vrai
i ← 1
Tant que (i < N) Et ok Faire
j ← 0
Tant que (j < i) Et ok Faire
Si M[i, j] ≠ M[j, i] Alors
ok ← Faux
Sinon
j ← j + 1
FinSi
Fin Tant que
i ← i + 1
Fin Tant que
Retourner ok
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j | Entier |
ok | Booléen |
En Python
def Symetrique(M, N):
ok = True
i = 1
while (i < N) and ok:
j = 0
while (j < i) and ok:
if M[i, j] != M[j, i]:
ok = False
else:
j = j + 1
i = i + 1
return ok
Exemple vérifié. La matrice ci-dessous est symétrique ; la matrice M ne l’est pas, puisque M[1, 0] = 7 et M[0, 1] = 2.
| 0 | 1 | 2 | |
|---|---|---|---|
| 0 | 1 | 4 | 7 |
| 1 | 4 | 2 | 5 |
| 2 | 7 | 5 | 3 |
En détail
Pour N = 4, on fait au plus 6 comparaisons au lieu de 16 : la diagonale n’est pas testée, et chaque paire n’est comparée qu’une fois.
6.2 Triangulaire_Sup
Une matrice carrée est triangulaire supérieure lorsque tous les éléments situés au-dessous de la diagonale principale sont nuls. On parcourt la même zone que pour la symétrie.
Fonction Triangulaire_Sup (M : Mat, N : Entier) : Booléen
DEBUT
ok ← Vrai
i ← 1
Tant que (i < N) Et ok Faire
j ← 0
Tant que (j < i) Et ok Faire
Si M[i, j] ≠ 0 Alors
ok ← Faux
Sinon
j ← j + 1
FinSi
Fin Tant que
i ← i + 1
Fin Tant que
Retourner ok
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j | Entier |
ok | Booléen |
En Python
def Triangulaire_Sup(M, N):
ok = True
i = 1
while (i < N) and ok:
j = 0
while (j < i) and ok:
if M[i, j] != 0:
ok = False
else:
j = j + 1
i = i + 1
return ok
Exemple vérifié. La fonction retourne Vrai pour la matrice ci-dessous, et Faux pour la matrice symétrique du paragraphe 6.1.
| 0 | 1 | 2 | |
|---|---|---|---|
| 0 | 1 | 4 | 7 |
| 1 | 0 | 2 | 5 |
| 2 | 0 | 0 | 3 |
7. Transformations : diagonales, transposée, lignes, tris
7.1 InverserDiag1 et InverserDiag2
Procédure InverserDiag1(M, N) qui échange les éléments d’une matrice carrée de part et d’autre de sa diagonale principale : M[i, j] et M[j, i] échangent leurs valeurs. La matrice obtenue est la transposée de M.
Procédure InverserDiag1 (@M : Mat, N : Entier)
DEBUT
Pour i de 1 à N - 1 Faire
Pour j de 0 à i - 1 Faire
aux ← M[i, j]
M[i, j] ← M[j, i]
M[j, i] ← aux
Fin Pour
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j, aux | Entier |
Procédure InverserDiag2(M, N) qui échange les éléments de part et d’autre de la diagonale secondaire : M[i, j] et M[N - 1 - j, N - 1 - i] échangent leurs valeurs.
Procédure InverserDiag2 (@M : Mat, N : Entier)
DEBUT
Pour i de 0 à N - 2 Faire
Pour j de 0 à N - i - 2 Faire
aux ← M[i, j]
M[i, j] ← M[N - j - 1, N - i - 1]
M[N - j - 1, N - i - 1] ← aux
Fin Pour
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j, aux | Entier |
En Python
def InverserDiag1(M, N):
for i in range(1, N):
for j in range(i):
aux = M[i, j]
M[i, j] = M[j, i]
M[j, i] = aux
def InverserDiag2(M, N):
for i in range(N - 1):
for j in range(N - i - 1):
aux = M[i, j]
M[i, j] = M[N - j - 1, N - i - 1]
M[N - j - 1, N - i - 1] = aux
Sur la matrice M : à gauche après InverserDiag1, à droite après InverserDiag2. Les diagonales concernées ne bougent pas.
| 0 | 1 | 2 | 3 | |
|---|---|---|---|---|
| 0 | 5 | 7 | 4 | 2 |
| 1 | 2 | 3 | 6 | 9 |
| 2 | 9 | 2 | 0 | 5 |
| 3 | 1 | 8 | 3 | 7 |
| 0 | 1 | 2 | 3 | |
|---|---|---|---|---|
| 0 | 7 | 3 | 8 | 1 |
| 1 | 5 | 0 | 2 | 9 |
| 2 | 9 | 6 | 3 | 2 |
| 3 | 2 | 4 | 7 | 5 |
Remarque importante. On ne parcourt que la moitié de la matrice : la zone au-dessous de la diagonale principale pour
InverserDiag1, la zone au-dessus de la diagonale secondaire pourInverserDiag2. Parcourir toute la matrice échangerait chaque paire deux fois : la matrice reviendrait à son état de départ, sans aucun message d’erreur.
7.2 Transposee
Pour une matrice qui n’est pas carrée, la transposée ne peut pas se construire sur place : M a NL lignes et NC colonnes, sa transposée M2 a NC lignes et NL colonnes.
Procédure Transposee (M : Mat, NL, NC : Entier, @M2 : Mat)
DEBUT
Pour i de 0 à NL - 1 Faire
Pour j de 0 à NC - 1 Faire
M2[j, i] ← M[i, j]
Fin Pour
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j | Entier |
En Python
def Transposee(M, NL, NC, M2):
for i in range(NL):
for j in range(NC):
M2[j, i] = M[i, j]
Exemple vérifié. La matrice 1 2 3 / 4 5 6, de 2 lignes et 3 colonnes, donne 1 4 / 2 5 / 3 6, de 3 lignes et 2 colonnes.
7.3 PermuterLignes
Procédure PermuterLignes(M, NC, L1, L2) qui échange le contenu des lignes L1 et L2, case par case.
Procédure PermuterLignes (@M : Mat, NC, L1, L2 : Entier)
DEBUT
Pour j de 0 à NC - 1 Faire
aux ← M[L1, j]
M[L1, j] ← M[L2, j]
M[L2, j] ← aux
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
j, aux | Entier |
En Python
def PermuterLignes(M, NC, L1, L2):
for j in range(NC):
aux = M[L1, j]
M[L1, j] = M[L2, j]
M[L2, j] = aux
Sur la matrice M, PermuterLignes(M, 4, 0, 3) donne la première ligne 2 9 5 7 et la dernière 5 2 9 1. L’échange de deux colonnes s’écrit de la même façon, avec Pour i de 0 à NL - 1 et M[i, C1], M[i, C2].
7.4 TrierLigne
Procédure TrierLigne(M, NC, NUML) qui trie par ordre croissant les éléments de la ligne NUML. Ce sont les tris d’un tableau, où T[j] est remplacé par M[NUML, j] : l’indice de ligne reste fixe.
Méthode 1 : tri à bulles
Procédure TrierLigne (@M : Mat, NC, NUML : Entier)
DEBUT
Répéter
Permut ← Faux
Pour j de 0 à NC - 2 Faire
Si M[NUML, j] > M[NUML, j + 1] Alors
aux ← M[NUML, j]
M[NUML, j] ← M[NUML, j + 1]
M[NUML, j + 1] ← aux
Permut ← Vrai
FinSi
Fin Pour
NC ← NC - 1
Jusqu'à Non(Permut) Ou (NC = 1)
FIN
TDOL
| Objet | Type / Nature |
|---|---|
j, aux | Entier |
Permut | Booléen |
Méthode 2 : tri par sélection
Procédure TrierLigne (@M : Mat, NC, NUML : Entier)
DEBUT
Pour j de 0 à NC - 2 Faire
posmin ← j
Pour k de j + 1 à NC - 1 Faire
Si M[NUML, k] < M[NUML, posmin] Alors
posmin ← k
FinSi
Fin Pour
Si posmin ≠ j Alors
aux ← M[NUML, j]
M[NUML, j] ← M[NUML, posmin]
M[NUML, posmin] ← aux
FinSi
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
j, k, posmin, aux | Entier |
Méthode 3 : tri par insertion
Procédure TrierLigne (@M : Mat, NC, NUML : Entier)
DEBUT
Pour j de 1 à NC - 1 Faire
aux ← M[NUML, j]
k ← j
Tant que (k > 0) Et (M[NUML, k - 1] > aux) Faire
M[NUML, k] ← M[NUML, k - 1]
k ← k - 1
Fin Tant que
M[NUML, k] ← aux
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
j, k, aux | Entier |
En Python
def TrierLigne(M, NC, NUML): # méthode 1, tri à bulles
Permut = True
while Permut and NC > 1:
Permut = False
for j in range(NC - 1):
if M[NUML, j] > M[NUML, j + 1]:
aux = M[NUML, j]
M[NUML, j] = M[NUML, j + 1]
M[NUML, j + 1] = aux
Permut = True
NC = NC - 1
def TrierLigne_Insertion(M, NC, NUML): # méthode 3
for j in range(1, NC):
aux = M[NUML, j]
k = j
while k > 0 and M[NUML, k - 1] > aux:
M[NUML, k] = M[NUML, k - 1]
k = k - 1
M[NUML, k] = aux
Sur la matrice M, les trois méthodes donnent pour la ligne 0 : 1 2 5 9. Les autres lignes ne sont pas modifiées.
Remarque importante. Dans la méthode 1,
NCest passé par valeur : le décrémenter ne modifie pas le nombre de colonnes du programme appelant. La condition d’arrêtNon(Permut) Ou (NC = 1)évite un dernier parcours vide.
7.5 TrierColonne
Procédure TrierColonne(M, NL, NUMC) qui trie par ordre croissant les éléments de la colonne NUMC. C’est le même algorithme, où l’indice de colonne reste fixe et l’indice de ligne varie.
Procédure TrierColonne (@M : Mat, NL, NUMC : Entier)
DEBUT
Pour i de 1 à NL - 1 Faire
aux ← M[i, NUMC]
k ← i
Tant que (k > 0) Et (M[k - 1, NUMC] > aux) Faire
M[k, NUMC] ← M[k - 1, NUMC]
k ← k - 1
Fin Tant que
M[k, NUMC] ← aux
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, k, aux | Entier |
En Python
def TrierColonne(M, NL, NUMC):
for i in range(1, NL):
aux = M[i, NUMC]
k = i
while k > 0 and M[k - 1, NUMC] > aux:
M[k, NUMC] = M[k - 1, NUMC]
k = k - 1
M[k, NUMC] = aux
Sur la matrice M, la colonne 1 devient 2 3 6 9.
Pour passer d’un tri de ligne à un tri de colonne, avec n’importe quelle méthode :
| Tri d’une ligne | Tri d’une colonne |
|---|---|
M[NUML, j] | M[i, NUMC] |
borne NC | borne NL |
8. Matrice et tableau
8.1 TransfertVersTableau
Procédure TransfertVersTableau(M, NL, NC, T) qui range les éléments de M, ligne après ligne, dans un tableau T de NL * NC éléments.
Méthode 1 : un compteur pour le tableau
Procédure TransfertVersTableau (M : Mat, NL, NC : Entier, @T : Tab)
DEBUT
k ← 0
Pour i de 0 à NL - 1 Faire
Pour j de 0 à NC - 1 Faire
T[k] ← M[i, j]
k ← k + 1
Fin Pour
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j, k | Entier |
Méthode 2 : l’indice calculé
Procédure TransfertVersTableau (M : Mat, NL, NC : Entier, @T : Tab)
DEBUT
Pour i de 0 à NL - 1 Faire
Pour j de 0 à NC - 1 Faire
T[i * NC + j] ← M[i, j]
Fin Pour
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j | Entier |
En Python
def TransfertVersTableau(M, NL, NC, T):
k = 0
for i in range(NL):
for j in range(NC):
T[k] = M[i, j]
k = k + 1
Sur la matrice M :
| T | 5 | 2 | 9 | 1 | 7 | 3 | 2 | 8 | 4 | 6 | 0 | 3 | 2 | 9 | 5 | 7 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Remarque importante. La case
M[i, j]va dansT[i * NC + j]: chaque ligne complète décale deNCcases. Inversement, la caseT[k]vient de la lignek Div NCet de la colonnek Mod NC.
8.2 TransfertVersMatrice
Procédure TransfertVersMatrice(T, N, M) qui remplit une matrice carrée M de N lignes à partir d’un tableau T de N * N entiers.
Méthode 1 : un compteur pour le tableau
Procédure TransfertVersMatrice (T : Tab, N : Entier, @M : Mat)
DEBUT
k ← 0
Pour i de 0 à N - 1 Faire
Pour j de 0 à N - 1 Faire
M[i, j] ← T[k]
k ← k + 1
Fin Pour
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j, k | Entier |
Méthode 2 : l’indice calculé
Procédure TransfertVersMatrice (T : Tab, N : Entier, @M : Mat)
DEBUT
Pour i de 0 à N - 1 Faire
Pour j de 0 à N - 1 Faire
M[i, j] ← T[i * N + j]
Fin Pour
Fin Pour
FIN
TDOL
| Objet | Type / Nature |
|---|---|
i, j | Entier |
En Python
def TransfertVersMatrice(T, N, M):
for i in range(N):
for j in range(N):
M[i, j] = T[i * N + j]
Le tableau du paragraphe 8.1 redonne exactement la matrice M, par les deux méthodes.
En détail
Le passage par un tableau sert surtout à trier tous les éléments d’une matrice : on transfère dans T, on trie T avec un tri du chapitre des tris, puis on retransfère dans M. La matrice est alors triée ligne après ligne.
9. De la matrice vers un fichier texte
Une ligne d’un fichier texte est une seule chaîne de caractères. Pour y écrire plusieurs nombres, on les convertit par Convch et on les concatène, séparés par un espace, avant d’écrire la ligne par Écrire_nl.
9.1 SauvegarderLignes
Procédure SauvegarderLignes(M, NL, NC, NomFich) qui enregistre chaque ligne de M sur une ligne du fichier texte NomFich, les éléments séparés par un espace. Le dernier élément d’une ligne n’est pas suivi d’un espace.
Procédure SauvegarderLignes (M : Mat, NL, NC : Entier, NomFich : Chaîne de caractères)
DEBUT
Ouvrir(NomFich, f, "w")
Pour i de 0 à NL - 1 Faire
ligne ← ""
Pour j de 0 à NC - 1 Faire
ligne ← ligne + Convch(M[i, j]) + " "
Fin Pour
Écrire_nl(f, Sous_chaine(ligne, 0, Long(ligne) - 1))
Fin Pour
Fermer(f)
FIN
TDOL
| Objet | Type / Nature |
|---|---|
f | Fichier texte |
i, j | Entier |
ligne | Chaîne de caractères |
En Python
def SauvegarderLignes(M, NL, NC, NomFich):
f = open(NomFich, "w")
for i in range(NL):
ligne = ""
for j in range(NC):
ligne = ligne + str(M[i, j]) + " "
f.write(ligne[0:len(ligne) - 1] + "\n")
f.close()
Sur la matrice M, le fichier obtenu contient :
5 2 9 1 7 3 2 8 4 6 0 3 2 9 5 7
Remarque importante — la technique du dernier séparateur. On ajoute un espace après chaque élément, puis on retire le dernier par
Sous_chaine(ligne, 0, Long(ligne) - 1). C’est la forme des corrigés officiels (session de contrôle 2023, matrice zoomée écrite avec le séparateur|). Elle évite de tester, à chaque élément, s’il est le dernier de la ligne.
9.2 SauvegarderColonnes
Procédure SauvegarderColonnes(M, NL, NC, NomFich) qui enregistre chaque colonne de M sur une ligne du fichier texte NomFich. Les deux boucles sont simplement inversées : la boucle extérieure porte sur les colonnes.
Procédure SauvegarderColonnes (M : Mat, NL, NC : Entier, NomFich : Chaîne de caractères)
DEBUT
Ouvrir(NomFich, f, "w")
Pour j de 0 à NC - 1 Faire
colonne ← ""
Pour i de 0 à NL - 1 Faire
colonne ← colonne + Convch(M[i, j]) + " "
Fin Pour
Écrire_nl(f, Sous_chaine(colonne, 0, Long(colonne) - 1))
Fin Pour
Fermer(f)
FIN
TDOL
| Objet | Type / Nature |
|---|---|
f | Fichier texte |
i, j | Entier |
colonne | Chaîne de caractères |
En Python
def SauvegarderColonnes(M, NL, NC, NomFich):
f = open(NomFich, "w")
for j in range(NC):
colonne = ""
for i in range(NL):
colonne = colonne + str(M[i, j]) + " "
f.write(colonne[0:len(colonne) - 1] + "\n")
f.close()
Sur la matrice M, le fichier obtenu contient :
5 7 4 2 2 3 6 9 9 2 0 5 1 8 3 7
C’est la transposée de M : la même que celle obtenue par InverserDiag1 au paragraphe 7.1.
9.3 SauvegarderMaxLigne
Procédure SauvegarderMaxLigne(M, NL, NC, NomFich) qui enregistre dans le fichier texte NomFich le maximum de chaque ligne de M, à raison d’une ligne du fichier par ligne de la matrice, sous la forme Ligne i : maximum.
Procédure SauvegarderMaxLigne (M : Mat, NL, NC : Entier, NomFich : Chaîne de caractères)
DEBUT
Ouvrir(NomFich, f, "w")
Pour i de 0 à NL - 1 Faire
max ← M[i, 0]
Pour j de 1 à NC - 1 Faire
Si M[i, j] > max Alors
max ← M[i, j]
FinSi
Fin Pour
Écrire_nl(f, "Ligne " + Convch(i) + " : " + Convch(max))
Fin Pour
Fermer(f)
FIN
TDOL
| Objet | Type / Nature |
|---|---|
f | Fichier texte |
i, j, max | Entier |
En Python
def SauvegarderMaxLigne(M, NL, NC, NomFich):
f = open(NomFich, "w")
for i in range(NL):
Max = M[i, 0]
for j in range(1, NC):
if M[i, j] > Max:
Max = M[i, j]
f.write("Ligne " + str(i) + " : " + str(Max) + "\n")
f.close()
Sur la matrice M, le fichier obtenu contient :
Ligne 0 : 9 Ligne 1 : 8 Ligne 2 : 6 Ligne 3 : 9
9.4 SauvegarderMinColonne
Procédure SauvegarderMinColonne(M, NL, NC, NomFich) qui enregistre le minimum de chaque colonne, sous la forme Colonne j : minimum.
Procédure SauvegarderMinColonne (M : Mat, NL, NC : Entier, NomFich : Chaîne de caractères)
DEBUT
Ouvrir(NomFich, f, "w")
Pour j de 0 à NC - 1 Faire
min ← M[0, j]
Pour i de 1 à NL - 1 Faire
Si M[i, j] < min Alors
min ← M[i, j]
FinSi
Fin Pour
Écrire_nl(f, "Colonne " + Convch(j) + " : " + Convch(min))
Fin Pour
Fermer(f)
FIN
TDOL
| Objet | Type / Nature |
|---|---|
f | Fichier texte |
i, j, min | Entier |
En Python
def SauvegarderMinColonne(M, NL, NC, NomFich):
f = open(NomFich, "w")
for j in range(NC):
Min = M[0, j]
for i in range(1, NL):
if M[i, j] < Min:
Min = M[i, j]
f.write("Colonne " + str(j) + " : " + str(Min) + "\n")
f.close()
Sur la matrice M, le fichier obtenu contient :
Colonne 0 : 2 Colonne 1 : 2 Colonne 2 : 0 Colonne 3 : 1
En détail
Le calcul du maximum d’une ligne est écrit directement dans la procédure. On peut aussi appeler la fonction MaximumLigne du paragraphe 4.6 : Convch(MaximumLigne(M, NC, i)). Elle figure alors dans le TDOL, avec la nature Fonction, et j et max en disparaissent.
10. D’un fichier texte vers une matrice
10.1 ChargerLignes
Procédure ChargerLignes(M, NL, NC, NomFich) qui remplit M à partir du fichier texte NomFich : chaque ligne du fichier contient une ligne de la matrice, NC entiers séparés par un espace, comme le fichier produit au paragraphe 9.1.
Chaque ligne lue est découpée : Pos donne la position du premier espace, Sous_chaine extrait le nombre qui le précède, Effacer supprime ce nombre et l’espace, et l’on recommence sur le reste.
Procédure ChargerLignes (@M : Mat, NL, NC : Entier, NomFich : Chaîne de caractères)
DEBUT
Ouvrir(NomFich, f, "r")
Pour i de 0 à NL - 1 Faire
Lire_ligne(f, ligne)
ligne ← ligne + " "
Pour j de 0 à NC - 1 Faire
p ← Pos(" ", ligne)
M[i, j] ← Valeur(Sous_chaine(ligne, 0, p))
ligne ← Effacer(ligne, 0, p + 1)
Fin Pour
Fin Pour
Fermer(f)
FIN
TDOL
| Objet | Type / Nature |
|---|---|
f | Fichier texte |
i, j, p | Entier |
ligne | Chaîne de caractères |
En Python
def ChargerLignes(M, NL, NC, NomFich):
f = open(NomFich, "r")
for i in range(NL):
ligne = f.readline()
ligne = ligne[:len(ligne) - 1] # retrait du "\n", en Python seulement
ligne = ligne + " "
for j in range(NC):
p = ligne.find(" ")
M[i, j] = int(ligne[0:p])
ligne = ligne[p + 1:]
f.close()
Appliquée au fichier du paragraphe 9.1, la procédure redonne exactement la matrice M.
Remarque importante — l’espace sentinelle. Le dernier nombre d’une ligne n’est suivi d’aucun espace. Sans l’instruction
ligne ← ligne + " ", la recherche de l’espace échoue sur ce dernier nombre : pourligne = "1",Pos(" ", ligne)retourne -1, etSous_chaine(ligne, 0, -1)n’a pas de sens. On ajoute donc un espace à la fin de la ligne avant de la découper : chaque nombre est alors suivi d’un espace. C’est l’opération inverse de la technique du dernier séparateur.
Remarque importante. La matrice est remplie par la procédure : elle est passée par référence (par adresse),
@M. Sans le@, la procédure remplirait une copie, et la matrice du programme appelant resterait inchangée.
En détail
Le nombre de lignes NL est connu : la lecture se fait avec une boucle Pour, sans Fin_fichier. Lorsque le nombre de lignes n’est pas connu, on utilise Tant que Non(Fin_fichier(f)) et on compte les lignes lues, comme au paragraphe 10.2.
10.2 ChargerTexteMat
Procédure ChargerTexteMat(M, NL, NomFich) qui remplit une matrice de caractères M, de 50 colonnes, à partir du fichier texte NomFich : chaque ligne du fichier devient une ligne de la matrice, complétée par des # si elle contient moins de 50 caractères. NL reçoit le nombre de lignes du fichier.
Méthode 1 : compléter case par case
Procédure ChargerTexteMat (@M : MatC, @NL : Entier, NomFich : Chaîne de caractères)
DEBUT
Ouvrir(NomFich, f, "r")
NL ← 0
Tant que Non(Fin_fichier(f)) Faire
Lire_ligne(f, ligne)
Pour j de 0 à 49 Faire
Si j < Long(ligne) Alors
M[NL, j] ← ligne[j]
Sinon
M[NL, j] ← "#"
FinSi
Fin Pour
NL ← NL + 1
Fin Tant que
Fermer(f)
FIN
TDOL
| Objet | Type / Nature |
|---|---|
f | Fichier texte |
j | Entier |
ligne | Chaîne de caractères |
Méthode 2 : compléter la chaîne d’abord
Procédure ChargerTexteMat (@M : MatC, @NL : Entier, NomFich : Chaîne de caractères)
DEBUT
Ouvrir(NomFich, f, "r")
NL ← 0
Tant que Non(Fin_fichier(f)) Faire
Lire_ligne(f, ligne)
Tant que Long(ligne) < 50 Faire
ligne ← ligne + "#"
Fin Tant que
Pour j de 0 à 49 Faire
M[NL, j] ← ligne[j]
Fin Pour
NL ← NL + 1
Fin Tant que
Fermer(f)
FIN
Le TDOL est le même.
En Python
def ChargerTexteMat(M, NomFich):
global NL
f = open(NomFich, "r")
NL = 0
ligne = f.readline()
while ligne != "":
ligne = ligne[:len(ligne) - 1]
for j in range(50):
if j < len(ligne):
M[NL, j] = ligne[j]
else:
M[NL, j] = "#"
NL = NL + 1
ligne = f.readline()
f.close()
Exemple vérifié. Pour un fichier de trois lignes Bac 2027, Matrices et fichiers et ABN, NL reçoit 3 et la matrice contient, lignes complétées jusqu’à la colonne 49 :
Bac 2027########################################## Matrices et fichiers############################## ABN###############################################
En détail
On suppose que chaque ligne du fichier compte au plus 50 caractères et que le fichier compte au plus 20 lignes. Le nombre de lignes n’étant pas connu, le parcours se fait par Tant que Non(Fin_fichier(f)), et NL, passé par référence, sert à la fois de compteur et d’indice de la ligne à remplir.
11. Matrice et fichier de données
Dans un fichier de données, chaque élément est écrit et relu tel quel, sans conversion ni découpage : un fichier d’entiers reçoit des entiers.
11.1 Mat_Vers_Dat
Procédure Mat_Vers_Dat(M, NL, NC, NomFich) qui enregistre les éléments de M, ligne après ligne, dans le fichier d’entiers NomFich.
Procédure Mat_Vers_Dat (M : Mat, NL, NC : Entier, NomFich : Chaîne de caractères)
DEBUT
Ouvrir(NomFich, f, "wb")
Pour i de 0 à NL - 1 Faire
Pour j de 0 à NC - 1 Faire
Écrire(f, M[i, j])
Fin Pour
Fin Pour
Fermer(f)
FIN
TDOL
| Objet | Type / Nature |
|---|---|
f | FEnt |
i, j | Entier |
11.2 Dat_Vers_Mat
Procédure Dat_Vers_Mat(M, NL, NC, NomFich) qui remplit M à partir du fichier d’entiers NomFich, qui contient NL * NC entiers rangés ligne après ligne. Le nombre d’éléments est connu : la lecture se fait avec deux boucles Pour.
Procédure Dat_Vers_Mat (@M : Mat, NL, NC : Entier, NomFich : Chaîne de caractères)
DEBUT
Ouvrir(NomFich, f, "rb")
Pour i de 0 à NL - 1 Faire
Pour j de 0 à NC - 1 Faire
Lire(f, M[i, j])
Fin Pour
Fin Pour
Fermer(f)
FIN
TDOL
| Objet | Type / Nature |
|---|---|
f | FEnt |
i, j | Entier |
En Python
from pickle import dump, load
def Mat_Vers_Dat(M, NL, NC, NomFich):
f = open(NomFich, "wb")
for i in range(NL):
for j in range(NC):
dump(int(M[i, j]), f)
f.close()
def Dat_Vers_Mat(M, NL, NC, NomFich):
f = open(NomFich, "rb")
for i in range(NL):
for j in range(NC):
M[i, j] = load(f)
f.close()
Un aller-retour Mat_Vers_Dat puis Dat_Vers_Mat redonne exactement la matrice M.
Remarque importante. Le nom logique du fichier est le premier paramètre de
Écrireet deLire:Écrire(f, M[i, j]), jamaisÉcrire(M[i, j], f). L’inversion est une erreur sanctionnée à la correction du bac.
En détail
En Python, int(M[i, j]) convertit l’élément numpy en entier Python avant l’écriture ; dump(M[i, j], f) fonctionnerait aussi, mais enregistrerait un objet numpy.
12. Les erreurs les plus fréquentes
Chaque conséquence a été obtenue en exécutant l’instruction erronée sur la matrice M.
| Instruction erronée | Instruction correcte | Conséquence |
|---|---|---|
max ← 0 | max ← M[0, 0] | sur une matrice d’éléments négatifs, le maximum retourné est 0 |
Position du maximum avec ≥ | avec > | la dernière occurrence est retenue : (3, 1) au lieu de (0, 2) |
SommeDiagonales sans Si N Mod 2 = 1 | avec la correction | pour N impair, la case centrale est comptée deux fois : 30 au lieu de 25 sur 1 2 3 / 4 5 6 / 7 8 9 |
InverserDiag1 avec Pour j de 0 à N - 1 | Pour j de 0 à i - 1 | chaque paire est échangée deux fois : la matrice est inchangée |
Écrire_nl() dans la boucle sur j | après la boucle sur j | un élément affiché par ligne |
Écrire_nl(f, ligne) sans Sous_chaine | Sous_chaine(ligne, 0, Long(ligne) - 1) | chaque ligne du fichier se termine par un espace : "5 2 9 1 " |
Découpage sans ligne ← ligne + " " | avec l’espace sentinelle | Pos retourne -1 sur le dernier nombre de la ligne |
Procédure ChargerLignes (M : Mat, …) | @M : Mat | la matrice du programme appelant n’est pas remplie |
Écrire(M[i, j], f) | Écrire(f, M[i, j]) | erreur sanctionnée au bac : le fichier est le premier paramètre |
Vérification avec deux boucles Pour | deux boucles Tant que | résultat juste, mais la matrice entière est parcourue même après un contre-exemple |
13. Retenons
Indices. Les lignes vont de
0àNL - 1, les colonnes de0àNC - 1. Une ligne :ifixe,jvarie. Une colonne :jfixe,ivarie.
Zones. Diagonale principale
i = j, diagonale secondairei + j = N - 1. Pour échanger autour d’une diagonale, on ne parcourt que la moitié de la matrice.
Extremums. On initialise avec un élément de la matrice, jamais avec 0. La comparaison stricte retient la première occurrence.
Recherche et vérification. On s’arrête au premier élément trouvé ou au premier contre-exemple : boucles
Tant que.
Matrice et tableau.
M[i, j]correspond àT[i * NC + j];T[k]correspond àM[k Div NC, k Mod NC].
Vers un fichier texte. On convertit par
Convch, on concatène avec un séparateur, on retire le dernier séparateur, puisÉcrire_nl.
Depuis un fichier texte. On ajoute un séparateur sentinelle à la fin de la ligne, puis on découpe par
Pos,Sous_chaine,ValeuretEffacer.
Fichier de données. Chaque élément s’écrit et se relit tel quel :
Écrire(f, M[i, j]),Lire(f, M[i, j]).
| Tâche | Boucle |
|---|---|
| Parcours complet, calcul, remplissage | deux Pour |
| Recherche, vérification | deux Tant que |
| Saisie contrôlée | Répéter … Jusqu'à |
| Lecture d’un fichier au nombre de lignes connu | Pour |
| Lecture d’un fichier au nombre de lignes inconnu | Tant que Non(Fin_fichier(f)) |
ABN Academy · Anis Ben Nacib · Résumé « Les matrices — modules classiques » · 4ᵉ SI
Pour aller plus loin : le cours complet, les exercices corrigés et le quiz dans Les tableaux à deux dimensions.

