¶
Feuille 4
2022
On a vu l'exemple de la fonction map
en cours qui
construit un nouveau tableau en appliquant une fonction f
passée en argument à chaque élément du tableau.
Sans utiliser les méthodes équivalente de Array
écrire
les fonctions suivante:
Écrire une fonction forEach(t,f)
qui execute la fonction
f
sur le tableau t
(ie. en séquence
sur chaque element de t
). Elle ne renvoie rien, seul les
effets de bord nous intéressent
> forEach( ["Pif", "Hercule", "Placid","Muzo"],
=>console.log("Salut "+x))
(x)
Salut Pif
Salut Hercule
Salut Placid
Salut Muzoundefined
>
function forEach(t,f){
for( let i in t)
f(t[i])
}
Écrire une fonction exists (t,f)
ou f est une fonction
booléenne ou prédicat (ie qui renvoie true
ou
false
)
Telle que exists([a1 , ... , an],f)
vérifie si au moins
un élément de la liste satisfait le prédicat f
(elle
renvoie alors true
, sinon elle renvoie
false
)
> exists([1, 2, 3],( x => x% 2 === 0)) ;
`true
function exists(t,f){
let i=t.length;
while(i>0){
--;
iif(f(t[i])===true)
return true}
{
}return false;
}
ou version recursive
function exists(t,f){
let [p,...r]=t
if (p===undefined) {return false}
else{return f(p)||exists(r,f)}
}
Écrire une fonction filter (t,f)
qui renvoie tous les
éléments du tableau t
qui satisfont le prédicat
f
. L'ordre des éléments du tableau d'entrée est
préservé.
> filter ( [1,2, 3, 4, 5],(x=>x%2===0))
2, 4 ]
[ >
function filter(t,f){
let res=[];
for(let i=0;i<t.length;i++){
if(f(t[i])){res.push(t[i])}
}return res
}
ou version récursive
function filter(t,f){
let find =(t,accu)=>{
let [p,...r]=t
if(t.length<1){return accu}
else {return f(p)?find(r,(accu.push(p),accu)):find(r,accu)
}
}return find(t,[])
}
Écrire une fonction map2(f,t1,t2)
qui se comporte comme
map
mais qui prend 2 tableaux en argument et une fonction à
2 arguments.
map2(f,[a1, ..., an],[b1, ..., bn])
renvoie
[f(a1,b1), ...,f(an,bn)]
.
> map2 ( (x,y)=>x+y , [1, 2, 3],[4, 5, 6])
5, 7, 9 ] [
On pourra lever une exception si les tableaux n'on pas la meme
taille. On peut aussi choisir de renvoyer false
function map2(f,t1,t2){
if(t1.length != t2.length){
throw new Error("les tableaux doivent être de meme taille" )
}let res=[];
for(let i=0;i<t1.length;i++){
.push(f(t1[i],t2[i]))
res
}return res;
}
Écrire une fonction exists2(f,t1,t2)
, identique à
exists
, mais pour un prédicat f
à deux
arguments et donc deux tableaux en argument.
On pourra lever une exception si les tableaux n'on pas la meme
taille. On peut aussi choisir de renvoyer false
> exists2 ((x,y)=>(y%x===0),[2, 4, 8],[11, 12, 13])
true
> exists2 ((x,y)=>(y%x===0),[2, 4, 8],[11, 13, 115])
false
>
function exists2(f,t1,t2){
if(t1.length != t2.length){
throw new Error ( "les tableaux doivent être de meme taille" )
}let i=t1.length;
while(i>0){
--;
iif(f(t1[i],t2[i])===true)
return true}
{
}return false;
}
Écrire une fonction partition(t,f)
telle que
partition(t,f)
renvoie un objet
{ok:t1, ko:t2)
, où t1
est le tableau de tous
les éléments de t
qui satisfont le prédicat f
,
et t2
est la liste de tous les éléments de t
qui ne satisfont pas f
. L'ordre des éléments dans la liste
d'entrée est préservé.
> partition ([1, 2, 3, 4, 5], (x)=> x % 2 === 0)
ok: [ 2, 4 ], ko: [ 1, 3, 5 ] }
{ >
function partition(t,f){
function part (t,yes, no){
let [p,...r]=t;
if (t.length<1){return {ok:yes,ko:no}}
else{
return f(p)?part(r,(yes.push(p),yes), no): part(r,yes, (no.push(p),no))
}
}
return part (t,[], [])
}
Écrire une fonction qui compte le nombre de mot d'un texte.
On considérera que les mots sont toujours séparés par des espaces.
> compteMots("Tout a l'air si compliqué")
5
>
function compteMots(s){
return s.split(" ").length;
}
Écrire une fonction qui compte le nombre de phrase d'un texte. On considérera que les phrases toujours séparées par des points suivies d'un espace.
let texte=`
Tout a l'air si compliqué. Tout est si simple pourtant.
Si j'avais eu la lune, si l'amour suffisait, tout serait changé.`
> comptePhrases(texte)
3
>
function comptePhrases(s){
return s.split(". ").length;
}
Écrire deux fonctions somme
et produit
prenant en argument un chaîne caractère contenant uniquement des nombres
et renvoyant respectivement leur somme et leur produit.
> somme("1 2 8 6")
17
> produit("1 2 8 6")
96
>
function somme(s){
let res=0;
.split(" ").forEach(x=>res+=0+Number(x)); // conversion obligatoire !!!
sreturn res;
}
//comme précédemment avec * ,ou plus classique
function produit(s){
let res=1;
let t= s.split(" ");
for(let i=0;i<t.length;i++){
*=Number(t[i]) // le Number pourrait être omis
res// avec * conversion vers number
} return res
}
ou avec la méthode reduce
function produit(s){
return s.split(" ").reduce(
, valeurCourante) => accumulateur * valeurCourante,
(accumulateur1
;
) }
Écrire une fonction qui prend un caractère français et si c'est une
voyelles accentuée ou le ç
renvoie la version sans accent
ou sans cédille; sinon elle renvoie le caractère inchangé
> sansDiacritique("é")
'e'
> sansDiacritique("à")
'a'
> sansDiacritique("u")
'u'
en utilisant juste indexOf
c'est pas du tout optimal
...
function sansDiacritique(l){
if ("àâä".indexOf(l)!=-1){return "a"}
if("éèêë".indexOf(l)!=-1){return "e"}
if("îï".indexOf(l)!=-1){return "i"}
if("ôö".indexOf(l)!=-1){return "o"}
if("ùûü".indexOf(l)!=-1){return "u"}
if(l==="ÿ"){return "y"}
if(l==="ç"){return "c"}
return l
}
Écrire une fonction qui prend une chaîne de caractère français et renvoie une version sans accent et sans cédille.
function sansDiacritiqueChaine(s){
="";
resfor(let i=0;i<s.length;i++){
+=sansDiacritique(s[i])
res
}return res
}
En utilisant split , map et join
function sansDiacritiqueChaine(s){
return s.split("").map(sansDiacritique).join("")
}
Ou optimal et plus générale, mais moins compréhensible sans rentrer dans les acharnes des encodages ... voir stackoverflow
let s="après l'été à dubaï"
> s.normalize("NFD").replace(/[\u0300-\u036f]/g, "")
"apres l'ete a dubai"
>
Écrire une fonction qui trie les mots d'un texte par ordre alphabétique. On considérera que les mots sont sans accents (on pourra s'y ramener avec la question précédente) et toujours séparés par des espaces .
On renverra un tableau triés (avec éventuellement des doublons), et mettant tout les mots en minuscule.
let texteSansAccent=`Tout a l'air si complique. Tout est si simple
pourtant. Si j'avais eu la lune, si l'amour suffisait, tout serait
change.`
> triMots(texteSansAccent)
['a', 'change.',
'complique.', 'est',
'eu', "j'avais",
"l'air", "l'amour",
'la', 'lune,',
'pourtant.', 'serait',
'si', 'si',
'si', 'si',
'simple', 'suffisait,',
'tout', 'tout',
'tout'
]
function triMots(s){
return s.toLowerCase().split(" ").sort()
}
Pour avoir quelque chose d'un peu plus propre
il faut utiliser une Expression_régulière dans split
function triMots(s){
return s.toLowerCase().split(/[ ';,!?]/).sort()
}
Deux chaîne de caractère sont des anagrammes s' ils ont même longueurs sont composés des même lettres, mais dans des ordres potentiellement différents.
Écrire une fonction qui teste si deux chaines sont des anagrammes.
On pourra utiliser les méthodes split , sort et join vues dans les corrections précédentes
> EstAnagramme("romain","manoir")
true
> EstAnagramme("sortie","toiser")
true
> EstAnagramme("posture","poste")
false
>
function EstAnagramme (str1, str2) {
//si les longueurs
//sont différente ce n'est pas des anagram
if (str1.length !== str2.length) {
return false;
}
//sinon on tri les caractères des deux chaînes.
var s1 = str1.split('').sort().join('');
var s2 = str2.split('').sort().join('');
//on compare les deux chaînes triées.
return (s1 === s2);
}
Les matrices peuvent être vues comme des tableaux à deux dimensions.
On a vu dans la feuille d'exercice précédente une fonction pour créer un
tableau de longueur n
rempli 0
. On veut ici
une fonction pour créer une matrice n x m
rempli de
0
> creerMatrice(3,4)
0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] ]
[ [ >
function creerMatrice(n,m){
let mat=[];
for(let i=0;i<n;i++){
let colj=[]
for(let j=0;j<m;j++){
=0
colj[j]
}=colj;
mat[i]
}return mat;
}
Ecrire une fonction qui créer une matrice n x m
initialisée avec des nombre aléatoires entre 0
et
n*m
.
On rappel que la fonction Math.random
permet de générer un nombre aléatoire entre 0
et
1
(exclu). Et que Math.floor
permet d'obtenir
la partie entière.
> creerMatrice(3,5)
3, 7, 12, 9, 6 ], [ 6, 14, 14, 3, 14 ], [ 5, 13, 0, 0, 7 ] ]
[ [ > creerMatrice(3,5)
10, 3, 13, 14, 0 ], [ 12, 6, 11, 6, 7 ], [ 0, 11, 13, 15, 4 ] ]
[ [ > creerMatrice(3,5)
14, 9, 1, 12, 8 ], [ 13, 2, 3, 11, 6 ], [ 3, 4, 1, 3, 12 ] ]
[ [ >
function RandomInt(n){return Math.floor(Math.random()*(n+1)) }
function creerMatrice(n,m){
let max=n*m;
let mat=[];
for(let i=0;i<n;i++){
let colj=[]
for(let j=0;j<m;j++){
=RandomInt(max)
colj[j]
}=colj;
mat[i]
}return mat;
}
On peut calculer le produit \(n_1 \times n_2\) de la façon suivante :
Le procédé s’arrête lorsque \(n_1\) tombe à zéro.
Écrire une fonction multRusse
implémentant cette
idée.
function multRusse(a, b) {
let res = 0;
while (a > 0) {
if (0 === (a % 2)) { //pair
= a / 2;
a = 2 * b;
b
}else { //impair
= res + b;
res --;
a
}
}return res;
}
// ou si on copie le pseudo code de wikipedia
function multRusse2(a, b) {
let res = 0;
while (a > 0) {
if (0 === (a % 2)) { //pair
}else { //impair
= res + b;
res --;
a
}
= a / 2;
a = 2 * b;
b
}return res;
}