Plan
Langage Java
• Opérateurs ++ et --
• Opérateurs de traitement de bits
• Opérateurs d'affectation
• Tableaux
• Chaînes de caractères
• Constantes énumérées Algorithmique
• QuickSort
• Tri par comptage
• Tri fusion
• Tri Shell
++, --
x = ++i;
équivaut à
i = i + 1;
x = i;
x = i++;
équivaut à
x = i;
i = i + 1;
x = --i;
équivaut à
i = i - 1;
x = i;
x = i--;
équivaut à
x = i;
i = i - 1;
Attention ! Ne s'applique qu'à des
variables : (i + j)++ est incorrect.
Opérateurs de traitement de bits
& ET bit à bit
| OU inclusif bit à bit
^ OU exclusif bit à bit
~ Négation bit à bit
<< Décalage à gauche
>> Décalage à droite, garde le ±
>>> Décalage à droite, sans signe Exemples en binaire
1001 & 0101 /* 0001 */
1001 | 0101 /* 1101 */
1001 ^ 0101 /* 1100 */
~1001 /* 0110 */
10011011 << 2
/* 01101100 */
10011011 >> 3
/* 00010011 */
final static int CLASSE2 = 2;
final static int FUMEUR = 4;
final static int FNOMBREUSE = 8;
final static int CVERMEILLE = 16;
static void Train(int billet)
{ if ((billet & CLASSE2) != 0) { ... }
if ((billet & FUMEUR) != 0) { ... }
if ((billet & (FNOMBREUSE
| CVERMEILLE)) != 0) Reduction(billet);
}...
billet = (ALLERRETOUR | CLASSE2 | FNOMBREUSE) & ~FUMEUR &
~CVERMEILLE ...
Opérateurs d'affectation
var op= expr
var = (T)((var) op (expr))
x *= y + 3;
x <<= 2;
billet &= ~FUMEUR;
op est l'un des opérateurs suivants : + - * / % << >> & ^ |
Si la variable var est de type T
Tableaux
int[] a;
boolean[][] b;
Déclaration
Construction
a = new int[N];
b = new boolean[N][M]
Utilisation a [i] = 3;
if (b[i][j])
…
Tableaux
int [] a = {12, 14, 6};
int [] b = new int[3];
int [][] c = {{1, 5, 1}, {2, 2, 0}} ;
int [][] d = new int[3][] ; int [][] e = new int[3][4] ; Correct
Incorrect
int [3] a = {12, 14, 6};
int [] b = new int[] ;
int Pascal[][] = { {1},
{1, 1},
{1, 2, 1},
{1, 3, 3, 1}, {1, 4, 6, 4, 1}
};
Pascal[0][0] vaut 1, Pascal[4][2] vaut 6,
Pascal[1][2] n'est pas encore défini.
Accès aux tableaux
La classe String
String s = "abc";
char[] t = {'a', 'b', 'c'};
String s = new String(t);
byte[] t = {97, 98, 99};
String s = new String(t);
En Java, les "string" sont des
objets, et non des types primitifs.
La classe String contient
plusieurs méthodes commodes.
Création
String two =
String.valueOf(1);
String Pi =
String.valueOf(3.14f);
String Vrai =
String.valueOf(true);
NB. On peut convertir dans l'autre sens, en utilisant des méthodes de la classe java.lang
Conversions
char[] t = {'a', 'b', 'c'};
String s1 = new String(t);
String s2 = "abc";
String s3 = "AbC";
if (s1.equals(s2)) // True if (s1.equals(s3)) // False if (s1.equalsIgnoreCase(s3))
// True
if ((s2.compareTo(s3)) < 0) // False
Comparaisons
charAt() compareTo()
concat() copyValueOf()
endsWith() equals() equalsIgnoreCase() getBytes() getChars() hashCode()
indexOf() intern()
lastIndexOf() length() regionMatches() replace() startsWith() substring()
toCharArray() toLowerCase() toString() toUpperCase()
trim() valueOf()
Conclusion: garder son manuel Java à portée de main...
Méthodes de la classe String
La classe java.lang.StringBuffer Les chaînes de type "String" ne sont pas modifiables. Pour avoir des chaînes modifiables, on utilise la classe "StringBuffer".
StringBuffer s = new StringBuffer ();
StringBuffer t = new
StringBuffer ("Salut");
s.append("Bon").append ("jour");
// s contient "Bonjour"
Priorités décroissantes
(paramètres) [] . ++ -- + - ~ ! (type)
* / %
+ - +chaîne
* &
<< >> >>>
< <= > >= instanceof
== !=
&
^
|
&&
||
?:
= += … op=
QuickSort
static void QuickSort(int g, int d) {
int i, m, v;
if (g < d) {
v = a[g];
m = g;
for (i = g + 1; i <= d; ++i) if (a[i] < v)
Echanger(++m, i);
Echanger(m, g);
QuickSort(g, m - 1);
QuickSort(m + 1, d);
} }
Exemple
v = a[g]; // En bleu m = g;
for (i = g + 1; i <= d; ++i) if (a[i] < v)
Echanger(++m, i);
Echanger(m, g);
Exemple
if (a[i] < v) Echanger(++m, i);
v = 18. En rouge, a[++m] et a[i]
Borne inférieure sur les tris
Combien faut-il de comparaisons pour trier une liste ?
Chaque comparaison générant deux possibilités, k comparaisons permettront de génerer au plus 2k permutations distinctes. Or il y a n! permutations possibles pour un ensemble à n éléments. Il faut donc log2(n!) comparaisons au minimum, soit, à l'aide de Stirling,
n (log2 n - log2 e) + 1/2 log2 n
= n log2 n + o(n log2 n)
Complexité de Quicksort Quicksort utilise en moyenne O(n log n) comparaisons
Soit CN le nombre moyen de com- paraisons. On a C0 = C1 = 0 et
CN = N + 1 +
Σ
(Ck-1 + CN-k)D'où
NCN = N(N + 1) + 2
Σ
Ck-1NCN - (N - 1)CN-1 = 2N + 2CN-1 NCN = 2N + (N + 1)CN-1
1
N 1 ≤ k ≤ N
1 ≤ k ≤ N
= + = +
Σ
CN N + 1
CN-1 N
2 N + 1
2 k+1 C2
3 3 ≤ k ≤ N
5 2 0 1 3 2 1 1 1 2 2
2 2 3 6 8 9 10 11 13 15
Tri par comptage
1 3 4 9 10 9 6 7 4 8 10 4 5 1 5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
2 2 3 6 7 9 10 11 13 15
1 5 1 2 3 6 7 9 10 11 13 15
1 5 5 1 2 3 6 6 9 10 11 13 15
1 1 3 4 4 4 5 5 6 7 8 9 9 10 10
Cumulé Nb d'entrées
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
Fusion de deux listes triées
Tri fusion
a 1 3 5 5 7
b 2 3 4 6
On compare a[i] et b[j], ce qui donne c[i + j].
Si a[i] ≤ b[j], i++;
Si a[i] > b[j], j++;
On coupe le tableau en deux, on trie chaque moitié, on interclasse.
Complexité O(n log n) mais nécessite un espace de O(n).
static int[] b = new int[N];
static void TriFusion(int g, int d) {
int i, j, k, m;
if (g < d) {
m = (g + d)/2;
TriFusion(g, m);
TriFusion(m + 1, d);
for (i = g; i <= m; i++) b[i] = a[i];
for (j = m + 1; j <= d; j++) b[d+m+1-j] = a[j];
i = g;
j = d;
for (k = g; k <= d; k++) a[k] = (b[i] < b[j]) ?
b[i++] : b[j--];
} }
Tri Shell
Idée : faire un tri par insertion pour les sous-suites
t[0], t[0+h], t[0+ 2h], t[0+3h], … t[1], t[1+h], t[1+ 2h], t[1+3h], … t[2], t[2+h], t[2+ 2h], t[2+3h], …
où h = …, 121, 40, 13, 4, 1 h1 = 1 et hn+1 = 3hn + 1
1 20 15 19 21 10 14 7 5 24 1 13 16 12 5 1 12
5 20 1 5 15 19 21 10 14 7 5 24 1 13 16 12 20 1 5 16 21
1 14 15 20 7 13 19 1 5 1 7 5 10 14 13 16 12 15 19 21 24 20 1 1 5 5 7 10 12 13 14 15 16 19 20 21 24 5 10 12 24
Tri Shell (programme)
static void TriShell() {
int h = 1;
do
h = 3 * h + 1;
while (h <= N);
do {
h = h / 3;
for (int i = h; i < N; ++i) if (a[i] < a[i-h])
{
int v = a[i], j = i;
do {
a[j] = a[j - h];
j = j - h;
}
while (j >= h && a[j - h] > v);
a[j] = v;
}
}
while (h > 1);
}
• Le tri shell avec la suite 1, 4,13,
40, 121, … nécessite au plus O(n3/2) comparaisons (admis)
• La complexité exacte est
inconnue! L'expérience montre que c'est un bon algorithme en pratique, facile à implanter.
Complexité du tri shell