34.7. Astuces assorties

do # Q[n] = Q[n - Q[n-1]] + Q[n - Q[n-2]] for n>2 # Nécessaire de casser l'expression en des termes intermédiaires. # car Bash ne gère pas très bien l'arithmétique des tableaux complexes. let "n1 = $n - 1" # n-1 let "n2 = $n - 2" # n-2 t0=`expr $n - ${Q[n1]}` # n - Q[n-1] t1=`expr $n - ${Q[n2]}` # n - Q[n-2] T0=${Q[t0]} # Q[n - Q[n-1]] T1=${Q[t1]} # Q[n - Q[n-2]] Q[n]=`expr $T0 + $T1` # Q[n - Q[n-1]] + Q[n - ![n-2]] echo -n "${Q[n]} " if [ `expr $n % $LONGUEURLIGNE` -eq 0 ] # Formatte la sortie. then # mod echo # Retour chariot pour des ensembles plus jolis. fi done echo exit 0 # C'est une implémentation itérative la Q-series. # L'implémentation récursive plus intuitive est laissée comme exercice. # Attention: calculer cette série récursivement prend *beaucoup* de temps.

--

Bash supporte uniquement les tableaux à une dimension, néanmoins une petite astuce permet de simuler des tableaux à plusieurs dimensions.

Exemple 26-9. Simuler un tableau à deux dimensions, puis son test

#!/bin/bash
# Simuler un tableau à deux dimensions.

# Un tableau à deux dimensions stocke les lignes séquentiellement.

Lignes=5
Colonnes=5

declare -a alpha     # char alpha [Lignes] [Colonnes];
                     # Déclaration inutile.

charge_alpha ()
{
local rc=0
local index


for i in A B C D E F G H I J K L M N O P Q R S T U V W X Y
do
  local ligne=`expr $rc / $Colonnes`
  local colonne=`expr $rc % $Lignes`
  let "index = $ligne * $Lignes + $colonne"
  alpha[$index]=$i   # alpha[$ligne][$colonne]
  let "rc += 1"
done  

# Un peu plus simple
#   declare -a alpha=( A B C D E F G H I J K L M N O P Q R S T U V W X Y )
# mais il manque néanmoins le "bon goût" d'un tableau à deux dimensions.
}

affiche_alpha ()
{
local ligne=0
local index

echo

while [ "$ligne" -lt "$Lignes" ]  # Affiche dans l'ordre des lignes -
do                                # les colonnes varient
                                  # tant que ligne (la boucle externe) reste
				  # identique
  local colonne=0
  
  while [ "$colonne" -lt "$Colonnes" ]
  do
    let "index = $ligne * $Lignes + $colonne"
    echo -n "${alpha[index]} "  # alpha[$ligne][$colonne]
    let "colonne += 1"
  done

  let "ligne += 1"
  echo

done  

# Un équivalent plus simple serait
#   echo ${alpha[*]} | xargs -n $Colonnes

echo
}

filtrer ()     # Filtrer les index négatifs du tableau.
{

echo -n "  "

if [[ "$1" -ge 0 &&  "$1" -lt "$Lignes" && "$2" -ge 0 && "$2" -lt "$Colonnes" ]]
then
    let "index = $1 * $Lignes + $2"
    # Maintenan, l'affiche après rotation.
    echo -n " ${alpha[index]}"  # alpha[$ligne][$colonne]
fi    

}
  



rotate ()  # Bascule le tableau de 45 degrés
{          # (le "balance" sur le côté gauche en bas).
local ligne
local colonne

for (( ligne = Lignes; ligne > -Lignes; ligne-- ))  # Traverse le tableau en
#	sens inverse.
do

  for (( colonne = 0; colonne < Colonnes; colonne++ ))
  do

    if [ "$ligne" -ge 0 ]
    then
      let "t1 = $colonne - $ligne"
      let "t2 = $colonne"
    else
      let "t1 = $colonne"
      let "t2 = $colonne + $ligne"
    fi  

    filtrer $t1 $t2   # Filtre les index négatifs du tableau.
  done

  echo; echo

done 

# Rotation du tableau inspirée par les exemples (pp. 143-146) de
# "Advanced C Programming on the IBM PC", par Herbert Mayer
# (voir bibliographie).

}


#-----------------------------------------------------#
charge_alpha     # Charge le tableau.
affiche_alpha    # L'affiche.
rotate           # Le fait basculer sur 45 degrés dans le sens contraire des
                 # aiguilles d'une montre.
#-----------------------------------------------------#


# C'est une simulation assez peu satisfaisante.
#
# Exercices:
# ---------
# 1)  Réécrire le chargement du tableau et les fonctions d'affichage
#   + d'une façon plus intuitive et élégante.
#
# 2)  Comprendre comment les fonctions de rotation fonctionnent.
#     Astuce: pensez aux implications de l'indexage arrière du tableau.

exit 0

Un tableau à deux dimensions est essentiellement équivalent à un tableau à une seule dimension mais avec des modes d'adressage supplémentaires pour les références et les manipulations d'éléments individuels par la position de la << ligne >> et de la << colonne >>.

Pour un exemple encore plus élaboré de simulation d'un tableau à deux dimensions, voir Exemple A-11.