Pseudo-code

La définition générale d'un algorithme ne spécifie rien sur les instructions à utiliser, juste qu'elles doivent être décrites en un nombre fini de mots. Un pseudo-code est une proposition d'instructions possibles pour décrire un algorithme, compréhensibles par un humain.

Ce n'est cependant pas une langue car il n'y a pas de place pour l'ambiguïté ni l'invention : tout doit y être rigoureusement défini, et chaque étape élémentaire doit être réalisable en un temps fini par un humain :

Rappelez-vous les trois premières règles de la définition d'un algorithme qui sont faciles à respecter.

Ce n'est pas non plus un langage informatique dont le but est d'être compris par un ordinateur. Il est communément admis que tout algorithme peut être écrit en pseudo-code :

Définition

Un pseudo-code est une succession de lignes qui seront exécutées en séquence les unes à la suite des autres. Chaque ligne est composée d'une instruction qu'il faut réaliser avant de passer à la ligne suivante.

Avant de définir précisément le pseudo-code, notez la thèse (hypothèse) fondamentale de l'informatique :

Thèse de Church-Turing

Tout programme (et donc algorithme) peut s'écrire sous la forme d'un pseudo-code (et réciproquement).

La thèse de Church-Turing a été initialement formulée pour les Machines de Turing mais (nous le verrons bien plus tard) pseudo-code et machines de Turing sont deux notions équivalentes. Notez que cette affirmation n'est pas démontrée mais que toutes les tentatives (et il y en a eu) pour infirmer cette affirmation ont été des échecs.

Pseudo-code et langages de programmation

Les langages de programmation classiques comme python, java ou encore rust se transcrivent aisément en pseudo-code et réciproquement. Ce sont deux notions équivalentes :

Éléments de pseudo-code

Briques de base

Commençons par décrire la grammaire de base du pseudo-code :

Algorithmes en pseudo-code

Un programme et un algorithme doivent posséder des paramètres d'entrées En pseudo-code, un algorithme est une suite d'instructions qui, a partir de paramètres d'entrée, rend une sortie. Considérons par exemple la description de l'algorithme de recherche d'un élément dans une liste :

Nom : recherche
Entrées :
    T : un tableau d'entiers
    x : un entier
Programme :
    parcourir chaque élément de t jusqu'à trouver un élément dont la valeur est égale à la valeur de x.
    Si on trouve un tel élément, rendre "Vrai"
    Sinon rendre "Faux"

En pseudo-code, cela va donner ça :

algorithme recherche(T: [entier],
                     x: entier     # entier recherché dans t
                    )  booléen:   # Vrai si x est dans t

    pour chaque e de T:
        si e == x:
            rendre Vrai
    rendre Faux

Le programme est un bloc. La definition du bloc (jusqu'aux :) est constitué :

  1. du mot-clé algorithme qui détermine la nature du bloc
  2. suit le du nom du programme
  3. puis ses paramètres d'entrées entre parenthèses. Chaque paramètre est décrit par son nom suivit de son type
  4. enfin, le type de sortie de l'algorithme qu'on fait précéder d'une flèche.

Si on a besoin d'information supplémentaire pour qu'un lecteur puisse mieux comprendre le pseudo-code on peut ajouter des commentaires en les faisant commencer par un #. Ne mettez pas trop de commentaires, normalement le pseudo-code et le nom des variables doit suffire. On a ici juste décrit ce que fait l'algorithme avec ses paramètres d'entrées.

La description des types de paramètres est reprise du format python : https://docs.python.org/fr/3.13/library/typing.html

Terminons par un petit exercice :

Adaptez le pseudo code de l'algorithme `recherche(T: [entier], x: entier) → booléen){.language-} précédent pour créer l'algorithme :

nombre(T: [entier], x: entier)  entier

Cet algorithme rend le nombre de fois où x est présent dans T

corrigé

algorithme nombre(T: [entier], x: entier)  entier:
    nb  0
    pour chaque e de T:
        si e == x:
            nb  nb + 1
    rendre nb

Fonctions

Un algorithme est constitué uniquement d'instructions de base. Mais rien n'empêche de réutiliser des algorithmes déjà écrit en les appelant par leur nom. Ces algorithmes intermédiaires sont appelées fonctions.

Écrire du bon pseudo-code

Un bon pseudo-code doit être compréhensible en tant que tel, sans commentaires.

Pour cela il faut :

Leurs noms importent peu, seuls leurs fonctions sont importantes. Vous pouvez donc utiliser les mots qui vous plaisent, du moment qu'ils sont compréhensible pour vous et — surtout — pour votre lecteur. Le plus souvent, on utilisera un mix de python et de français, ou d'anglais.

Opérateurs utilisés en pseudo-code

Plusieurs opérateurs ressemblant à l'égalité sont utilisés en pseudo-code, attention à bien comprendre leurs différences.

"Abus" de notation

On se permettra, lorsque l'instruction est assez claire de procéder à des raccourci pour rendre le pseudocode plus digeste. Attention, la plupart de ces opérations ne seront pas des opérations élémentaires !

Définitions de variables

Le but d'un pseudo-code est d'être explicite, c'est pourquoi :

Mais cela ne doit pas rendre le code lourd. On se permettra donc, lorsqu'il n'y a pas d’ambiguïté possible, l'abus de notations qui crée et affecte une variable en une seule fois :

Vous verrez aussi parfois cet opérateur remplacé par le mot "soit", en particulier lorsqu'il y a plusieurs variables à créer :


    
        
            
                
            
        
        
            
                
            
        
        
            
                
                    
                        
                            
                            
                            
                            
                            
                            
                        
                    
                    
                        
                    
                    
                        
                            
                        
                    
                    
                        
                            
                        
                    
                    
                        
                            
                        
                    
                    
                        
                            
                            
                        
                    
                    
                        
                            
                        
                    
                    
                        
                            
                            
                            
                            
                            
                        
                    
                    
                        
                            
                            
                            
                            
                            
                            
                            
                        
                    
                
            
        
        
            
                
            
        
        
            
                
            
        
    
    
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
    

Répétitions

répéter k fois:
    ...

Pour :

pour chaque i de [1 .. k]:
    ...

Répétitions par borne

Tout un tas de variations sont possibles, du moment que ce soit compréhensible. Par exemple :

pour i de a à b:
    ...

Ou encore :

pour i=a à i=b:
    ...

Pour :

pour chaque i de [a .. b]:
    ...

Répétitions à pas fixé

pour i de a à b par par pas de k:
    ...

ou encore :

pour chaque i de [a .. b] par pas de k:
    ...

pour :

i  a
tant que i  b:
  ...

  i  i + k

Affectation d'une tranche de tableau

T[a:b]  k

pour :

pour chaque i de [a .. b[:
    T[i]  k

Fonctionne aussi pour :

T[:]  k

Qui correspond à :

pour chaque i de [0 .. T.longueur[:
    T[i]  k

Ou encore à :

T[a:b]  T'[a':]

Qui correspond à :

pour chaque i de [0 .. b-a[:
    T[a + i]  T'[a' + i]

Les affectations de tranches ne sont pas une instruction simple, mais nécessitent plusieurs instructions : ceux de la boucle sous-jacente.

Ainsi, le code suivant nécessite $1 + j - i$ instructions (1 instruction de création du nouveau tableau puis j-i affectations) :

T'  un nouveau tableau contenant T[i:j]  # j - i + 1 instructions en 1 ligne

Concaténation

Avec deux tableaux :

T  T1 + T2

pour :

T  un nouveau tableau de taille T1.longueur + T2.longueur

pour chaque i de [0 .. T1.longueur[:
    T[i]  T1[i]
pour chaque i de [0 .. T2.longueur[:
    T[T1.longueur + i]  T2[i]