Aller au contenu

Chaînes de caractères

Chaque exercice est fourni avec un fichier Python à compléter et un énoncé « papier » distribué à l'élève et reproduit ci-dessous.

Remarques importantes

  1. Les exercices de cette page ne sont pas classés par ordre de « difficulté », cette notion de difficulté étant subjective et dépendante de chaque élève.

  2. Les solutions proposées ne sont que des propositions !
    Il existe d'autres codes valables pour répondre à chaque problème que ceux proposés ici : il ne faut pas hésiter à les soumettre à votre enseignant pour qu'il vous donne son avis sur les idées mises en oeuvre.

Correspondance

On considère des mots à trous : ce sont des chaînes de caractères contenant uniquement des majuscules et des caractères * (étoile). Le caractère * remplace exactement une lettre majuscule.
Par exemple INFO*MA*IQUE, ***I***E** et *S* sont des mots à trous.

Dans cet exercice, la fonction correspond() doit :

  • prendre en paramètres deux chaînes de caractères de même longueur mot et mot_a_trousmot_a_trous est un mot à trous comme indiqué ci-dessus,

  • renvoyer :

    • True si on peut obtenir mot en remplaçant convenablement les caractères '*' de mot_a_trous.
    • False sinon.

Exemples

>>> correspond('INFORMATIQUE', 'INFO*MA*IQUE')
True

>>> correspond('AUTOMATIQUE', '*****M*****')
False

>>> correspond('PYTHON', 'JAV*S*R**T')
AssertionError: Les deux mots n'ont pas la même longueur
  1. Compléter la définition de la fonction correspond(), sans oublier d'ajouter l'assertion signalée dans l'exemple précédent.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    def correspond(mot, mot_a_trous):
        """
        mot, mot_a_trous - 
        Sortie: 
        >>> correspond('INFORMATIQUE', 'INFO*MA*IQUE')
        True
        >>> correspond('AUTOMATIQUE', '*****M*****')
        False
        """
        pass
    
    
    
    if __name__ == '__main__':
        import doctest
        doctest.testmod()
    
  2. Compléter le docstring de cette fonction.

  3. Ajouter au moins deux nouveaux tests avec affichage dans la partie principale du programme (le main).
Une solution possible
 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
def correspond(mot, mot_a_trous):
    """
    mot, mot_a_trous - str, chaîne de caractères de même longueur
    Sortie: bool - True si les caractères de mot et mot_a_trous
            correspondent un à un, éventuellement avec une * dans mot_a_trous,
            False sinon
    >>> correspond('INFORMATIQUE', 'INFO*MA*IQUE')
    True
    >>> correspond('AUTOMATIQUE', '*****M*****')
    False
    """
    assert len(mot) == len(mot_a_trous), "Les deux mots n'ont pas la même longueur"
    for i in range(len(mot)):
        if mot_a_trous[i] != '*' and mot_a_trous[i] != mot[i]:
            return False
    return True



if __name__ == '__main__':
    import doctest
    doctest.testmod()

    print(correspond('NSI', '*S*') == True)
    print(correspond('REUSSI', '**USSE') == False)

Renverser

On considère une fonction renverse(), prenant en paramètre une chaîne de caractères non vide mot et qui renvoie une chaîne de caractères en inversant ceux de la chaîne mot.

Exemples

>>> renverse("informatique")
'euqitamrofni'

>>> renverse('')
AssertionError: La chaîne est vide
  1. Compléter la définition de la fonction renverse(), sans oublier d'ajouter l'assertion signalée dans l'exemple précédent.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    def renverse(mot):
        """
        mot - 
        Sortie: 
    
        >>> renverse("informatique")
        'euqitamrofni'
        """
        pass
    
    
    
    if __name__ == '__main__':
        import doctest
        doctest.testmod()
    
  2. Compléter le docstring de cette fonction.

  3. Ajouter au moins deux nouveaux tests avec affichage dans la partie principale du programme (le main).
Une solution possible
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
def renverse(mot):
    """
    mot - str
    Sortie: str - chaîne constituée des caractères de mot
            « écrits » dans l'ordre contraire 

    >>> renverse("informatique")
    'euqitamrofni'
    """
    assert len(mot) > 0, "La chaîne est vide"
    result = ''
    for caractere in mot:
        result = caractere + result
    return result


if __name__ == '__main__':
    import doctest
    doctest.testmod()

    print(renverse("renverser") == "resrevner")  
    print(renverse("radar") == "radar")  

Renverser doublement

On considère une fonction renverser() qui prend en paramètre une chaîne de caractères formée uniquement des caractères 'D' et 'G'. Cette fonction renvoie une chaîne de caractères qui correspond à la chaîne passée en paramètre « doublement renversée », c’est-à-dire :

  • chaque 'D' est transformé en 'G' et vice-versa ;
  • le premier caractère est devenu le dernier, le deuxième est devenu l'avant-dernier, etc...

Exemples

>>> renverser('DDGD')
'GDGG'

>>> renverser('GDGGDDG')
'DGGDDGD'

>>> renverser('')
AssertionError: La chaîne est vide
  1. Compléter la définition de la fonction renverser(), sans oublier d'ajouter l'assertion signalée dans l'exemple précédent.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    def renverser(chaine):
        """
        chaine -    
        Sortie: 
    
        >>> renverser('DDGD')
        'GDGG'
        >>> renverser('GDGGDDG')
        'DGGDDGD'
        """
        pass
    
    
    
    if __name__ == '__main__':
        import doctest
        doctest.testmod()
    
  2. Compléter le docstring de cette fonction.

  3. Ajouter au moins deux nouveaux tests avec affichage dans la partie principale du programme (le main).
Une solution possible
 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
def renverser(chaine):
    """
    chaine - str, chaîne de caractères formée uniquement de 'D' et de 'G'
    Sortie: str - chaîne « doublement renversée », basée sur chaine,
            dans laquelle 'D' et 'G' sont échangés puis écrite de la fin
            vers le début 

    >>> renverser('DDGD')
    'GDGG'
    >>> renverser('GDGGDDG')
    'DGGDDGD'
    """
    assert len(chaine) > 0, "La chaîne est vide"
    resultat = ""
    for carac in chaine:
        if carac == 'D':
            resultat = 'G' + resultat
        else:
            resultat = 'D' + resultat

    return resultat



if __name__ == '__main__':
    import doctest
    doctest.testmod()

    print(renverser('DGDGDG') == "DGDGDG")  
    print(renverser('DDDDDG') == "DGGGGG")

Nombre d'occurrences d'un caractère

Écrire une fonction nb_occurrences() qui prend en paramètres caractere, un caractère, et mot, une chaîne de caractères, et qui renvoie le nombre d’occurrences de caractere dans mot, c’est-à-dire le nombre de fois où caractere apparaît dans mot.

Exemples

>>> nb_occurrences('e', "sciences") 
2

>>> nb_occurrences('i',"mississippi") 
4

>>> nb_occurrences('a',"mississippi") 
0
  1. Compléter la définition de la fonction nb_occurrences().

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    def nb_occurrences(caractere, mot):
        """
        caractere - 
        mot - 
        Sortie: 
        >>> nb_occurrences('e', "sciences") 
        2
        >>> nb_occurrences('i',"mississippi") 
        4
        >>> nb_occurrences('a',"mississippi") 
        0
        """
        pass
    
    
    
    if __name__ == '__main__':
        import doctest
        doctest.testmod()
    
  2. Compléter le docstring de cette fonction.

  3. Ajouter au moins deux nouveaux tests avec affichage dans la partie principale du programme (le main).
Une solution possible
 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
def nb_occurrences(caractere, mot):
    """
    caractere - str, un caractère
    mot - str, une chaîne de caractères
    Sortie: int, nombre d'occurences de caractere dans mot
    >>> nb_occurrences('e', "sciences") 
    2
    >>> nb_occurrences('i',"mississippi") 
    4
    >>> nb_occurrences('a',"mississippi") 
    0
    """
    nb_occur = 0
    for carac in mot:
        if carac == caractere:
            nb_occur += 1
    return nb_occur


if __name__ == '__main__':
    import doctest
    doctest.testmod()

    print(nb_occurrences('e', "exemple") == 3)
    print(nb_occurrences('y', "oiseau") == 0)

Nombre de mots

Pour cet exercice :

  • On appelle « mot » une chaîne de caractères composée avec des caractères choisis parmi les 26 lettres minuscules ou majuscules de l'alphabet.
  • On appelle « phrase » une chaîne de caractères composée avec un ou plusieurs « mots » séparés entre eux par un seul caractère espace ' '.
  • Une « phrase » se finit soit par un point '.' qui est alors collé au dernier mot, soit par un point d'exclamation '!' ou d'interrogation '?' qui est alors séparé du dernier mot par un seul caractère espace ' '.

Après avoir remarqué le lien entre le nombre de mots et le nombres de caractères espace dans une phrase, programmer une fonction nombre_de_mots() qui prend en paramètre une phrase et renvoie le nombre de mots présents dans cette phrase.

Exemples

>>> nombre_de_mots('Le point d exclamation est separe !')
6

>>> nombre_de_mots('Il y a un seul espace entre les mots.')
9
  1. Compléter la définition de la fonction nombre_de_mots().

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    def nombre_de_mots(phrase):
        """
        phrase - 
        Sortie: 
        >>> nombre_de_mots('Le point d exclamation est separe !')
        6
        >>> nombre_de_mots('Il y a un seul espace entre les mots.')
        9
        """
        pass
    
    
    
    if __name__ == '__main__':
        import doctest
        doctest.testmod()
    
  2. Compléter le docstring de cette fonction.

  3. Ajouter au moins deux nouveaux tests avec affichage dans la partie principale du programme (le main).
Une solution possible
 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
def nombre_de_mots(phrase):
    """
    phrase - str, chaîne composée de lettres minuscules et majuscules,
            d'espaces et d'un point d'interrogation, d'un point d'exclamation
            ou d'un point  "normal"
    Sortie: int, nombre de mots dans la phrase, séparés par un espace
    >>> nombre_de_mots('Le point d exclamation est separe !')
    6
    >>> nombre_de_mots('Il y a un seul espace entre les mots.')
    9
    """
    nb_mots = 0
    for carac in phrase:
        if carac == ' ':
            nb_mots += 1
    if phrase[len(phrase)-1] == '.':
        nb_mots += 1
    return nb_mots



if __name__ == '__main__':
    import doctest
    doctest.testmod()

    print(nombre_de_mots('Bravo vous avez bien codé la fonction !') == 7)
    print(nombre_de_mots('Quelle est la meilleur manière de coder ?') == 7)

Palindromes

Un mot palindrome peut se lire de la même façon de gauche à droite ou de droite à gauche : bob, radar, et non sont des mots palindromes.

De même certains nombres sont eux aussi des palindromes : 33, 121, 345543.

L’objectif de cet exercice est d’obtenir un programme Python permettant de tester si un nombre est un nombre palindrome.

Pour remplir cette tâche, on vous demande de compléter le code de trois fonctions :

  • La fonction inverse_chaine() inverse l'ordre des caractères d'une chaîne de caractères chaine passée en paramètre et renvoie la chaîne inversée.

  • La fonction est_palindrome() teste si une chaine de caractères chaine est un palindrome. Elle renvoie True si c’est le cas et False sinon.

  • La fonction est_nbre_palindrome() teste si un nombre nbre est un palindrome. Elle renvoie True si c’est le cas et False sinon.

Exemples

>>> inverse_chaine('bac')
'cab'

>>> est_palindrome('NSI')
False

>>> est_palindrome('ISN-NSI')
True

>>> est_nbre_palindrome(214312)
False

>>> est_nbre_palindrome(213312)
True
  1. Compléter la définition de ces fonctions.

     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
    def inverse_chaine(chaine):
        """
        chaine - 
        Sortie: 
        >>> inverse_chaine('bac')
        'cab'
        """
        pass
    
    
    def est_palindrome(chaine):
        """
        chaine - 
        Sortie: 
        >>> est_palindrome('NSI')
        False
        >>> est_palindrome('ISN-NSI')
        True
        """
        pass
    
    
    def est_nbre_palindrome(nbre):
        """
        nbre - 
        Sortie: 
        >>> est_nbre_palindrome(214312)
        False
        >>> est_nbre_palindrome(213312)
        True
        """
        pass
    
    
    
    if __name__ == '__main__':
        import doctest
        doctest.testmod()
    
  2. Compléter les docstring de ces fonctions.

  3. Ajouter, pour chaque fonction, au moins un nouveau test avec affichage dans la partie principale du programme (le main).
Une solution possible
 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
def inverse_chaine(chaine):
    """
    chaine - str, une chaîne de caractères quelconques
    Sortie: str - chaîne constituée des caractères de chaine, dans l'ordre inverse
    >>> inverse_chaine('bac')
    'cab'
    """
    result = ""
    for caractere in chaine:
        result = caractere + result
    return result


def est_palindrome(chaine):
    """
    chaine - str, une chaîne de caractères quelconques
    Sortie: bool - True si chaine est un palindrome, False sinon
    >>> est_palindrome('NSI')
    False
    >>> est_palindrome('ISN-NSI')
    True
    """
    inverse = inverse_chaine(chaine)
    return inverse == chaine


def est_nbre_palindrome(nbre):
    """
    nbre - int, entier strictement positif
    Sortie: bool - True si nbre est un palindrome, False sinon
    >>> est_nbre_palindrome(214312)
    False
    >>> est_nbre_palindrome(213312)
    True
    """
    chaine = str(nbre)
    return est_palindrome(chaine)


if __name__ == '__main__':
    import doctest
    doctest.testmod()

    print(inverse_chaine('test') == 'tset')
    print(est_palindrome('radar') == True)
    print(est_palindrome('informatique') == False)
    print(est_nbre_palindrome(1234321) == True)
    print(est_nbre_palindrome(121212) == False)

Nombres narcissiques

On appelle nombre narcissique tout entier égal à la somme de ses p chiffres chacun élevé à la puissance p.

Exemples

  • 153 est narcissique car il a 3 chiffres et 1^3 + 5^3 + 3^3 = 153.
  • 8208 est narcissique car il a 4 chiffres et 8^4 + 2^4 + 0^4 + 8^4 = 8208.

L’objectif de cet exercice est d’obtenir un programme Python permettant de déterminer l'ensemble des nombres narcissiques jusqu'à un certain seuil.

Pour remplir cette tâche, on vous demande de compléter le code de deux fonctions :

  • La fonction est_narcisse() qui prend en paramètre un entier n positif ou nul et qui renvoie True lorsque n est narcissique et False sinon.

  • La fonction narcisses_jusqu_a() qui prend en paramètre un entier N positif ou nul et qui renvoie une chaîne de caractères constituée de l'ensemble des entiers narcissiques compris entre 0 et N séparés par des espaces.

Exemples

>>> est_narcisse(153)
True

>>> est_narcisse(8208)
True

>>> est_narcisse(10)
False

>>> narcisses_jusqu_a(1000)
'0 1 2 3 4 5 6 7 8 9 153 370 371 407 '
  1. Compléter la définition de ces fonctions.

     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
    def est_narcisse(n):
        """
        n – 
        Sortie: 
    
        >>> est_narcisse(153)
        True
        >>> est_narcisse(8208)
        True
        >>> est_narcisse(10)
        False
        """
        pass
    
    
    
    def narcisses_jusqu_a(N):
        """
        N – 
        Sortie: 
    
        >>> narcisses_jusqu_a(1000)
        '0 1 2 3 4 5 6 7 8 9 153 370 371 407 '
        """
        pass
    
    
    
    if __name__ == '__main__':
        import doctest
        doctest.testmod()
    
  2. Compléter les docstring de ces fonctions.

  3. Ajouter, pour chaque fonction, au moins un nouveau test avec affichage dans la partie principale du programme (le main).
Une solution possible
 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
def est_narcisse(n):
    """
    n – int, entier positif ou nul
    Sortie: bool – True si n est narcissique, c'est-à-dire un entier égal à
            la somme de ses p chiffres chacun élevé à la puissance p,
            False sinon

    >>> est_narcisse(153)
    True
    >>> est_narcisse(8208)
    True
    >>> est_narcisse(10)
    False
    """
    chaine = str(n)
    p = len(chaine)
    total = 0                   # Somme des p chiffres, chacun à la puissance p
    for chiffre in chaine:
        total = total + int(chiffre)**p

    if total == n:
        return True
    else:
        return False


def narcisses_jusqu_a(N):
    """
    N – int, entier positif ou nul
    Sortie: str – Tous les entiers narcissiques compris entre 0 et N,
            séparés par des espaces

    >>> narcisses_jusqu_a(1000)
    '0 1 2 3 4 5 6 7 8 9 153 370 371 407 '
    """
    narcisses = ""
    for i in range(N):
        if est_narcisse(i):
            narcisses = narcisses + str(i) + " "
    return narcisses


if __name__ == '__main__':
    import doctest
    doctest.testmod()

    print(est_narcisse(370) == True)    
    print(est_narcisse(371) == True)    
    print(est_narcisse(372) == False)    
    print(narcisses_jusqu_a(10000) == '0 1 2 3 4 5 6 7 8 9 153 370 371 407 1634 8208 9474 ')

Remplacer

Dans cet exercice, la fonction remplace_o_ou() doit :

  • prendre en paramètre une chaîne de caractères,

  • renvoyer une chaîne copie de celle donnée en paramètre mais dans laquelle les « o » ont été remplacés par des « ou », sauf lorsque « o » est suivi de « u » auquel cas, on remplace « ou » par « o ».

Exemples

>>> remplace_o_ou('loup')
'lop'

>>> remplace_o_ou('ououo')
'ooou'
  1. Compléter la définition de la fonction remplace_o_ou().

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    def remplace_o_ou(chaine):
        """
        chaine - 
        Sortie: 
    
        >>> remplace_o_ou('loup')
        'lop'
        >>> remplace_o_ou('ououo')
        'ooou'
        """
        pass
    
    
    
    if __name__ == '__main__':
        import doctest
        doctest.testmod()
    
  2. Compléter le docstring de cette fonction.

  3. Ajouter au moins deux nouveaux tests avec affichage dans la partie principale du programme (le main).
Une solution possible avec une boucle for
 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
def remplace_o_ou(chaine):
    """
    chaine - str, chaîne de caractères
    Sortie: str - chaine dans laquelle les « o » ont été remplacés par
            des « ou » et les « ou » ont été remplacés par « o »

    >>> remplace_o_ou('loup')
    'lop'
    >>> remplace_o_ou('ououo')
    'ooou'
    """
    res=''
    for indice in range(len(chaine)):
        if chaine[indice]=='o' and indice!=len(chaine)-1 and chaine[indice+1]=='u':
            res+='o'
        elif chaine[indice]=='o':
            res+='ou'
        elif chaine[indice]=='u' and chaine[indice-1]=='o':
            pass
        else:
            res+=chaine[indice]
    return res



if __name__ == '__main__':
    import doctest
    doctest.testmod()

    print(remplace_o_ou('uoou') == 'uouo')    
    print(remplace_o_ou('ouzo') == 'ozou')
Une solution possible avec une boucle while
 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
def remplace_o_ou(chaine):
    """
    chaine - str, chaîne de caractères
    Sortie: str - chaine dans laquelle les « o » ont été remplacés par
            des « ou » et les « ou » ont été remplacés par « o »

    >>> remplace_o_ou('loup')
    'lop'
    >>> remplace_o_ou('ououo')
    'ooou'
    """
    indice = 0
    result = ''
    while indice < len(chaine):
        if chaine[indice] == 'o':
            if indice+1 < len(chaine) and chaine[indice+1] == 'u':
                result += 'o'
                indice += 2
            else:
                result += 'ou'
                indice += 1
        else:
            result += chaine[indice]
            indice += 1
    return result



if __name__ == '__main__':
    import doctest
    doctest.testmod()

    print(remplace_o_ou('uoou') == 'uouo')    
    print(remplace_o_ou('ouzo') == 'ozou')