Aller au contenu

Recherches dans un tableau

Rechercher une valeur

Considérons le tableau suivant : nombres = [8, 7, 2, 10, 3, 1, 6, 5, 9, 4] et cherchons-y la valeur 5.

Contrairement à nous, l'ordinateur n'a pas une vue d'ensemble des valeurs, il ne peut pas immédiatement « voir » le 5 vers la fin du tableau.

Son approche est plus rudimentaire : il passe en revue tous les éléments du tableau jusqu'à trouver le 5 :

Recherche de 5

Cette méthode est appelée la recherche linéaire ou méthode par balayage.

La fonction lineaire

Compléter la fonction lineaire prenant en argument un tableau et une valeur x et renvoyant l'indice de la première occurrence de x dans tableau.

Si x n'est pas présent dans tableau, la fonction renverra None

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 5/5

.128013sy,dnh(Nle5[k:w;1oéS2pPqbta=ux].mi4vrc3_RgEf) è/050e0k0A0B0I0j0b0U0M0j0B0b0b0C010A0I0w010406050b0D0H0H0B0L0c040u0s0j0D0;0s0f0U020B0H0w0q0U0P0k0~0L0y0D0k0b050W0{0}0 110_0w04051w1p1z0W1w0_0e0I0K0)0+0-0/0g0I0Q0g0j1N0g0A0@050!0z0j0k1I0,0.011M1O1Q1O0A1W1Y1U0A0L1x0A0g0)140b0w0B0f0/0v011!1K010S0$0k0f1c0k1U1`1|211$241Y270H29040a0U0x0L0s0w0s0b0I17190Y1^0L0L0k0M2u1p2b0f1x0W1?2G1:1=1;1V0e2d0/1Q0f262r1U1F1H0*1#2Q0I2S0f0s2W1U0w2z1x2E2G2.0`1{192Y222%0L0~0j0@0r2D2=0^2;2c2@1$2_2{0@0v2 1|312E2P01360B2|040N3a2F0_3d340/3g3i0J3l3c2=3e3r0@0l3u1A2,1p2W2J0e1=2O3p010M2(2j0X1G1x2+0k2-303B3M0Y3U331J1$0n0@0Y0S3B3o3#0/0p0@0U3+3w3K0f0S0@2R0k0#2z3=3!2Z010?040h3 2?3-3f0@1-3|0D463e430d3u3;3,410f0@0E4e3K430T0o3u060U4w4j3?483%040S0s0L4i32474l0@0I4G4k220s3/042#4M4z4l0z0@0L1|0Q0k4p4843451q3V4N354W042g4$414(4;2^4a0B1X4c4@1$4r4s4u4x524y40224B0I3*4*3b544I4^044b0B4d5a2F4H4f0@0m4}3q4K5p420@0F4T551$0s0@0C0C5w5d354n5s434t5j0^535M5c3e4B2z0A0D0L0f5D3x5r5K4v4x5l3K5Q0Z5T5V5K5O5%0M0@0i184#5Z1p3X3T3C5`0W3F1p0A3H5 2M2H4`1Y2G3F1v3Z5E0/2z0H0O0S0B0n0k0O0g0N0@1h1j1l1n0U5J2:1C311w0R190L0t3h2t0t0d0U1Y3;5_3e1(1P1R1T6a5P4X5)5U5W5.5:5=3B0W5_040U2w0+6$0k5U0I0V2z6G1N2S0U0f001n0A0U1{0(0f0t0M1n0b3}1Z0M0 0U262m0c1?180U0D6;4D0f2B0I7b2z0f0K0s0I1Z056J3K6L1*1S2a4U565/045;2S6Y6!6`750e0t6g160U0G1A315}0Z0#0%04.

Étudions en détails le déroulement de cette fonction en comptant le nombre d'opérations:

  • l'algorithme est construit autour d'une boucle « Pour »,
  • à chaque itération, la variable i se voit affecter une nouvelle valeur : \(1\) affectation,
  • on teste ensuite si tableau[i] est égal à x : \(1\) accès à la valeur de tableau[i] et \(1\) comparaison,
  • s'il y a égalité on renvoie i : \(1\) retour,
  • en fin de boucle on renvoie None : \(1\) retour.

Remarque

Ce décompte du nombre d'opérations est simpliste. En réalité, Python exécute plus d'opérations.

Si l'on fait le total, on se rend compte que chaque tour de boucle (sans tenir compte du return) nécessite \(3\) opérations. Le return quant à lui, qu'il renvoie un indice ou None rajoute \(1\) opération à l'ensemble.

Dans l'exemple précédent, le 5 cherché était à l'indice 7. Il a donc fallu \(8\) itérations et \(3\times 8 +1=25\) opérations au total.

Compter les opérations ou les itérations

On considère toujours le tableau nombres = [8, 7, 2, 10, 3, 1, 6, 5, 9, 4] et l'on effectue des recherches linéaires.

  • La recherche de 8 nécessite une seule itération
  • La recherche de 8 nécessite une seule opération
  • La recherche de 6 nécessite \(19\) opérations
  • La recherche de 4 nécessite \(31\) opérations
  • ✅ 8 est à l'indice 0. Il faut donc bien une seule itération
  • ❌ Non car chaque itération nécessite à elle seule \(3\) opérations
  • ❌ 6 est à l'indice 6. Il faut donc \(7\) itérations et \(3\times 7 + 1= 22\) opérations
  • ✅ 4 est à l'indice 9. Il faut donc \(10\) itérations et bien \(3\times 10 + 1= 31\) opérations

Le décompte précis des opérations peut être laborieux et très sensible au langage de programmation ou aux instructions saisies pour mettre en œuvre l'algorithme.

Important

Nous allons donc désormais nous contenter de compter les itérations qui ne font que des opérations élémentaires.

Compter les itérations

On a modifié la fonction lineaire afin qu'elle renvoie le nombre d'itérations nécessaires effectuées lors de la recherche de x dans tableau. Cette nouvelle fonction s'appelle lineaire_bis

Si vous exécutez ce code, vous retrouverez le résultat précédent : rechercher 5 nécessite \(8\) itérations.

Modifier x et tableau (si besoin) afin que la recherche de x dans tableau nécessite :

  • 1 itération ;
  • 2 itérations ;
  • 5 itérations dans un tableau de 5 valeurs ;
  • 5 itérations dans un tableau de 6 valeurs ;
  • 5 itérations dans un tableau contenant 2 fois la valeur cherchée ;
  • 6 itérations dans un tableau de 6 valeurs sans que x ne soit présent dans tableau.

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Solution
  • 1 itération : Par exemple lineaire([0], 0)

  • 2 itérations : Par exemple lineaire([0, 1], 2)

  • 5 itérations dans un tableau de 5 valeurs : Par exemple lineaire([1, 2, 3, 4, 5], 5)
  • 5 itérations dans un tableau de 6 valeurs : Par exemple lineaire([1, 2, 3, 4, 5, 6], 5)
  • 5 itérations dans un tableau contenant 2 fois la valeur cherchée : Par exemple lineaire([1, 2, 3, 4, 5, 5], 5)
  • 6 itérations dans un tableau de 6 valeurs sans que x ne soit présent dans tableau : Par exemple lineaire([1, 2, 3, 4, 5, 6], 7)

On l'a deviné, l'algorithme effectue un maximum d'itérations dans deux cas de figure :

  • soit x est le dernier élément de tableau,
  • soit x n'est pas présent dans tableau.

Ce sont les deux pires des cas.

Cible en dernière position Cible absente

Dans chacun d'eux, si le tableau compte \(N\) éléments, il y aura \(N\) itérations. Le nombre d'itérations est égal à la taille du tableau. On dit que l'algorithme de recherche linéaire est de coût linéaire.

Rechercher le minimum

Le tri par sélection nécessite de trouver la valeur minimale du tableau afin de la placer en première position. Ceci fait on recommence à partir de la deuxième position, puis de la troisième, etc.

Nous nous intéressons dans cette partie à la recherche du minimum.

Rechercher le minimum
  • Dans le tableau \([3,\,8,\,7,\,1,\,2]\) la recherche du minimum nécessite \(4\) itérations
  • Dans le tableau \([1,\,2,\,3,\,4]\) la recherche du minimum nécessite \(4\) itérations
  • La recherche du minimum est plus courte s'il est placé au début du tableau
  • Dans le tableau \([8,\,8,\,8,\,8]\) la recherche du minimum nécessite \(1\) itération
  • ❌ Dans le tableau \([3,\,8,\,7,\,1,\,2]\) la recherche du minimum nécessite \(4\) itérations
  • ✅ Dans le tableau \([1,\,2,\,3,\,4]\) la recherche du minimum nécessite \(4\) itérations
  • ❌ La recherche du minimum est plus courte s'il est placé au début du tableau
  • ❌ Dans le tableau \([8,\,8,\,8,\,8]\) la recherche du minimum nécessite \(1\) itération

Il faut lire l'ensemble des valeurs une fois pour être sûr de bien déterminer le minimum. Donc pour un tableau de taille \(N\), il faut faire \(N\) itérations.

On l'a compris, la recherche du minimum nécessite de lire toutes les valeurs une seule fois : le coût est donc linéaire (proportionnel à la taille du tableau).

La fonction indice_du_minimum

Compléter la fonction indice_du_minimum prenant en argument un tableau et renvoyant l'indice de la première occurrence du minimum dans tableau.

On garantit que tableau est non vide.

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 5/5

.128013sy,dn6h(le5[k:w;1oS2p0Pbta=u]mi4vrc3_gf) /050e0k0z0A0F0j0b0P0J0j0A0b0b0B010z0F0v010406050b0C0E0E0A0I0c040t0s0j0C0+0s0f050Q0=0@0_0{0:0v04051b141e0Q1b0:0e0F0H0Z0#0%0)0h0F0M0h0j1s0h0z0.050U0y0j0k1n0$0(011r1t1v1t0z1B1D1z0z0I1c0z0h0Z0~0b0v0A0f0)0u011F1p010N0W0k0f0A0E0k1z1Y1!1)1H1,1D1/1;0.0a0P0x0I0s0v0s0b0F110f0P0S1W0I0I0k0J29141@0f1c0Q1U2m1R1T1S1A0e1_0)1v0f1.261z1k1m0!1G2w0F2y0f0s2C1z0v2f1c2k2m2Q0;1Z2a2E1*2J0I0^0j0.0r2j2U0/2T1^2W1H2Y2!0.0u2(1!2*2k2v012/0A2#040K2?2l0:2_2-0)2|2~0G312^2U2`370.0l3a333c352{0s2Z2}0.0g3a1f2O142C2p0e1T2u3k0J2K1=1c3v1d3t2S152)053B0S2P3j1o1H0n0.0S0N3r343Q0)0p0.0P3W3P2F2{0N0.2H1k0J0k0L0e0C0L0E2H0F0E0?3%2,3Y010-040i3}2V3 0f0.1O0k0A0C442`410O0o3h0P4j3$3X3)47040F3@3_3a4l3(1*0s0.0B4t2+453)3^0.0w4i4k4B2`3S040N3m4A4m2X3,4P4v1H0s3!4p133J2@4u3~4n0y0.0I1!0M0k4d3k41434!2l4J3k4E042%4?3O4%1*410d4T4 2.4)041|4/3 4;594n480A1C4a4c4}4^5a0.0O4g4H4k4I4Q3R3,3V4}4$4C4R04494b5c500.0m5D2.4S5j5s0)410D535y4V0.020j0z0q5P3d5e5g5C5K4U5M5F5H363,4r0f0F5*400.0D4h4}065q5`5r5%2{5,3^5.5X3k4x044z5w5k5d4p5p5x4K4*0T0C0I4Z2Q6c3k4o4q605/5^143M0k2m2N6t3u1l3w2p2s2n5f1D2m3v0:0Q0S0U0W0b04.