elle n'est pas récursive mais ça doit sans doute être plus efficace.
J'ai peur que cette dernière remarque soit à prendre au premier degré...
Faut-il que les étudiants soient bien intoxiqués de langages fonctionnels
pour imaginer systématiquement des solutions recursives aux problèmes les
plus simples ?
elle n'est pas récursive mais ça doit sans doute être plus efficace.
J'ai peur que cette dernière remarque soit à prendre au premier degré...
Faut-il que les étudiants soient bien intoxiqués de langages fonctionnels
pour imaginer systématiquement des solutions recursives aux problèmes les
plus simples ?
elle n'est pas récursive mais ça doit sans doute être plus efficace.
J'ai peur que cette dernière remarque soit à prendre au premier degré...
Faut-il que les étudiants soient bien intoxiqués de langages fonctionnels
pour imaginer systématiquement des solutions recursives aux problèmes les
plus simples ?
Primo, la recherche dichotomique dans un tableau en mémoire n'est pas une
plaie à coder, tout au plus un rapide échauffement des petits doigts pour le
petit déjeuner.
Primo, la recherche dichotomique dans un tableau en mémoire n'est pas une
plaie à coder, tout au plus un rapide échauffement des petits doigts pour le
petit déjeuner.
Primo, la recherche dichotomique dans un tableau en mémoire n'est pas une
plaie à coder, tout au plus un rapide échauffement des petits doigts pour le
petit déjeuner.
Charlie Gordon a écrit :elle n'est pas récursive mais ça doit sans doute être plus efficace.
J'ai peur que cette dernière remarque soit à prendre au premier degré...
Faut-il que les étudiants soient bien intoxiqués de langages fonctionnels
pour imaginer systématiquement des solutions recursives aux problèmes les
plus simples ?
J'ai cru que la solution récursive serait très lisible mais pas tant que
ça. Je me risque à proposer un code :
void *dicho(const void *key, const void *base, size_t nmemb, size_t size,
int (*compar) (const void *, const void *))
{
if (nmemb == 0)
return NULL;
else if (nmemb == 1)
return compar(key, base) == 0 ? (void *) base : NULL;
else
{
size_t m = (nmemb - 1) / 2;
const char *p = base, *mil = p + m * size;
int v = compar(key, mil);
if (v > 0)
return dicho(key, mil + size, nmemb - m - 1, size, compar);
else if (v < 0)
return dicho(key, p, m, size, compar);
else
return (void *) mil;
}
}
Charlie Gordon a écrit :
elle n'est pas récursive mais ça doit sans doute être plus efficace.
J'ai peur que cette dernière remarque soit à prendre au premier degré...
Faut-il que les étudiants soient bien intoxiqués de langages fonctionnels
pour imaginer systématiquement des solutions recursives aux problèmes les
plus simples ?
J'ai cru que la solution récursive serait très lisible mais pas tant que
ça. Je me risque à proposer un code :
void *dicho(const void *key, const void *base, size_t nmemb, size_t size,
int (*compar) (const void *, const void *))
{
if (nmemb == 0)
return NULL;
else if (nmemb == 1)
return compar(key, base) == 0 ? (void *) base : NULL;
else
{
size_t m = (nmemb - 1) / 2;
const char *p = base, *mil = p + m * size;
int v = compar(key, mil);
if (v > 0)
return dicho(key, mil + size, nmemb - m - 1, size, compar);
else if (v < 0)
return dicho(key, p, m, size, compar);
else
return (void *) mil;
}
}
Charlie Gordon a écrit :elle n'est pas récursive mais ça doit sans doute être plus efficace.
J'ai peur que cette dernière remarque soit à prendre au premier degré...
Faut-il que les étudiants soient bien intoxiqués de langages fonctionnels
pour imaginer systématiquement des solutions recursives aux problèmes les
plus simples ?
J'ai cru que la solution récursive serait très lisible mais pas tant que
ça. Je me risque à proposer un code :
void *dicho(const void *key, const void *base, size_t nmemb, size_t size,
int (*compar) (const void *, const void *))
{
if (nmemb == 0)
return NULL;
else if (nmemb == 1)
return compar(key, base) == 0 ? (void *) base : NULL;
else
{
size_t m = (nmemb - 1) / 2;
const char *p = base, *mil = p + m * size;
int v = compar(key, mil);
if (v > 0)
return dicho(key, mil + size, nmemb - m - 1, size, compar);
else if (v < 0)
return dicho(key, p, m, size, compar);
else
return (void *) mil;
}
}
Charlie Gordon a écrit :Primo, la recherche dichotomique dans un tableau en mémoire n'est pas une
plaie à coder, tout au plus un rapide échauffement des petits doigts pour
le petit déjeuner.
Parles-en à Plauger, voilà ce qu'il en dit dans son livre sur la
bibliothèque standard (page 353) :
Function bsearch : (...). The logic is simple but easy to get wrong.
C'est exactement mon avis et c'est aussi pour ça que je trouve que c'est
une plaie à coder : un bsearch c'est une mécanique de précision.
Néanmoins, je trouve le code de Plauger assez compliqué :
Charlie Gordon a écrit :
Primo, la recherche dichotomique dans un tableau en mémoire n'est pas une
plaie à coder, tout au plus un rapide échauffement des petits doigts pour
le petit déjeuner.
Parles-en à Plauger, voilà ce qu'il en dit dans son livre sur la
bibliothèque standard (page 353) :
Function bsearch : (...). The logic is simple but easy to get wrong.
C'est exactement mon avis et c'est aussi pour ça que je trouve que c'est
une plaie à coder : un bsearch c'est une mécanique de précision.
Néanmoins, je trouve le code de Plauger assez compliqué :
Charlie Gordon a écrit :Primo, la recherche dichotomique dans un tableau en mémoire n'est pas une
plaie à coder, tout au plus un rapide échauffement des petits doigts pour
le petit déjeuner.
Parles-en à Plauger, voilà ce qu'il en dit dans son livre sur la
bibliothèque standard (page 353) :
Function bsearch : (...). The logic is simple but easy to get wrong.
C'est exactement mon avis et c'est aussi pour ça que je trouve que c'est
une plaie à coder : un bsearch c'est une mécanique de précision.
Néanmoins, je trouve le code de Plauger assez compliqué :
Ah bon ? Peux-tu être plus explicite ?
> (Et je ne vois pas l'utilite du +1 dans a = m + 1).
Cela accélère la convergence : la clé est > au pivot donc l'element cherché
est forcément strictement au delà du pivot.
>> On peut dans ce cas améliorer légèrement l'efficacité de la recherche et
>> garantir de trouver le premier match en cas de doublons en remplacant les
>> deux tests sur cmp par un seul (laissé au lecteur à titre d'exercice ;-).
>
> Rien n'empeche de faire cela ici aussi, il suffit de tester l'egalite
> avant
> de retourner une valeur. C'est un gain meme si la valeur se trouve
> toujours dans le tableau.
Non, ce n'est pas loisible : dans le cas général on a plus de comparaisons
avec *key != *p, donc il est préférable de tester ces cas en premier.
Ah bon ? Peux-tu être plus explicite ?
> (Et je ne vois pas l'utilite du +1 dans a = m + 1).
Cela accélère la convergence : la clé est > au pivot donc l'element cherché
est forcément strictement au delà du pivot.
>> On peut dans ce cas améliorer légèrement l'efficacité de la recherche et
>> garantir de trouver le premier match en cas de doublons en remplacant les
>> deux tests sur cmp par un seul (laissé au lecteur à titre d'exercice ;-).
>
> Rien n'empeche de faire cela ici aussi, il suffit de tester l'egalite
> avant
> de retourner une valeur. C'est un gain meme si la valeur se trouve
> toujours dans le tableau.
Non, ce n'est pas loisible : dans le cas général on a plus de comparaisons
avec *key != *p, donc il est préférable de tester ces cas en premier.
Ah bon ? Peux-tu être plus explicite ?
> (Et je ne vois pas l'utilite du +1 dans a = m + 1).
Cela accélère la convergence : la clé est > au pivot donc l'element cherché
est forcément strictement au delà du pivot.
>> On peut dans ce cas améliorer légèrement l'efficacité de la recherche et
>> garantir de trouver le premier match en cas de doublons en remplacant les
>> deux tests sur cmp par un seul (laissé au lecteur à titre d'exercice ;-).
>
> Rien n'empeche de faire cela ici aussi, il suffit de tester l'egalite
> avant
> de retourner une valeur. C'est un gain meme si la valeur se trouve
> toujours dans le tableau.
Non, ce n'est pas loisible : dans le cas général on a plus de comparaisons
avec *key != *p, donc il est préférable de tester ces cas en premier.
Il n'est en effet pas nécessaire de tester nmemb == 1
Une petite remarque concernant le pointeur de fonction : j'utilise la
syntaxe (*compar)(x, y) pour qu'il soit bien visible que compar n'est
pas le nom d'une fonction,
Il n'est en effet pas nécessaire de tester nmemb == 1
Une petite remarque concernant le pointeur de fonction : j'utilise la
syntaxe (*compar)(x, y) pour qu'il soit bien visible que compar n'est
pas le nom d'une fonction,
Il n'est en effet pas nécessaire de tester nmemb == 1
Une petite remarque concernant le pointeur de fonction : j'utilise la
syntaxe (*compar)(x, y) pour qu'il soit bien visible que compar n'est
pas le nom d'une fonction,
/* bsearch function */
#include <stdlib.h>
void *(bsearch)(const void *key, const void *base,
size_t nelem, size_t size, _Cmpfun *cmp)
{ /* search sorted table by binary chop */
const char *p = base;
size_t n;
for (p = base, n = nelem; 0 < n; )
{ /* check midpoint of whatever is left */
const size_t pivot = n >> 1;
const char *const q = p + size * pivot;
const int val = (*cmp)(key, q);
if (val < 0)
n = pivot; /* search below pivot */
else if (val == 0)
return ((void *)q); /* found */
else
{ /* search above pivot */
p = q + size;
n -= pivot + 1;
}
}
return (NULL); /* no match */
}
/* bsearch function */
#include <stdlib.h>
void *(bsearch)(const void *key, const void *base,
size_t nelem, size_t size, _Cmpfun *cmp)
{ /* search sorted table by binary chop */
const char *p = base;
size_t n;
for (p = base, n = nelem; 0 < n; )
{ /* check midpoint of whatever is left */
const size_t pivot = n >> 1;
const char *const q = p + size * pivot;
const int val = (*cmp)(key, q);
if (val < 0)
n = pivot; /* search below pivot */
else if (val == 0)
return ((void *)q); /* found */
else
{ /* search above pivot */
p = q + size;
n -= pivot + 1;
}
}
return (NULL); /* no match */
}
/* bsearch function */
#include <stdlib.h>
void *(bsearch)(const void *key, const void *base,
size_t nelem, size_t size, _Cmpfun *cmp)
{ /* search sorted table by binary chop */
const char *p = base;
size_t n;
for (p = base, n = nelem; 0 < n; )
{ /* check midpoint of whatever is left */
const size_t pivot = n >> 1;
const char *const q = p + size * pivot;
const int val = (*cmp)(key, q);
if (val < 0)
n = pivot; /* search below pivot */
else if (val == 0)
return ((void *)q); /* found */
else
{ /* search above pivot */
p = q + size;
n -= pivot + 1;
}
}
return (NULL); /* no match */
}
Charlie Gordon a écrit :
/* bsearch function */
#include <stdlib.h>
void *(bsearch)(const void *key, const void *base,
size_t nelem, size_t size, _Cmpfun *cmp)
{ /* search sorted table by binary chop */
const char *p = base;
size_t n;
for (p = base, n = nelem; 0 < n; )
{ /* check midpoint of whatever is left */
const size_t pivot = n >> 1;
const char *const q = p + size * pivot;
const int val = (*cmp)(key, q);
if (val < 0)
n = pivot; /* search below pivot */
else if (val == 0)
return ((void *)q); /* found */
else
{ /* search above pivot */
p = q + size;
n -= pivot + 1;
}
}
return (NULL); /* no match */
}
T'as scanné le code ? t'as une version numérique du livre ? T'as quand
même pas recopié le code à la main, c'est copie conforme, aux espaces
près, de sa Figure 13.8 page 356 ?
Charlie Gordon a écrit :
/* bsearch function */
#include <stdlib.h>
void *(bsearch)(const void *key, const void *base,
size_t nelem, size_t size, _Cmpfun *cmp)
{ /* search sorted table by binary chop */
const char *p = base;
size_t n;
for (p = base, n = nelem; 0 < n; )
{ /* check midpoint of whatever is left */
const size_t pivot = n >> 1;
const char *const q = p + size * pivot;
const int val = (*cmp)(key, q);
if (val < 0)
n = pivot; /* search below pivot */
else if (val == 0)
return ((void *)q); /* found */
else
{ /* search above pivot */
p = q + size;
n -= pivot + 1;
}
}
return (NULL); /* no match */
}
T'as scanné le code ? t'as une version numérique du livre ? T'as quand
même pas recopié le code à la main, c'est copie conforme, aux espaces
près, de sa Figure 13.8 page 356 ?
Charlie Gordon a écrit :
/* bsearch function */
#include <stdlib.h>
void *(bsearch)(const void *key, const void *base,
size_t nelem, size_t size, _Cmpfun *cmp)
{ /* search sorted table by binary chop */
const char *p = base;
size_t n;
for (p = base, n = nelem; 0 < n; )
{ /* check midpoint of whatever is left */
const size_t pivot = n >> 1;
const char *const q = p + size * pivot;
const int val = (*cmp)(key, q);
if (val < 0)
n = pivot; /* search below pivot */
else if (val == 0)
return ((void *)q); /* found */
else
{ /* search above pivot */
p = q + size;
n -= pivot + 1;
}
}
return (NULL); /* no match */
}
T'as scanné le code ? t'as une version numérique du livre ? T'as quand
même pas recopié le code à la main, c'est copie conforme, aux espaces
près, de sa Figure 13.8 page 356 ?
tel jugement du tribunal de Becon-les-Bruyères
extern int f(), (*fp)(), (*apf[])(double);
[N'auraient-ils pas dû écrire
extern int f(void), (*fp)(void);
tel jugement du tribunal de Becon-les-Bruyères
extern int f(), (*fp)(), (*apf[])(double);
[N'auraient-ils pas dû écrire
extern int f(void), (*fp)(void);
tel jugement du tribunal de Becon-les-Bruyères
extern int f(), (*fp)(), (*apf[])(double);
[N'auraient-ils pas dû écrire
extern int f(void), (*fp)(void);
En news:48e6139f$0$10248$, candide va escriure:tel jugement du tribunal de Becon-les-Bruyères
Il n'y a pas de Tribunal à Bécon.
Non, il y a des différences entre les deux. La plus évidente
est que tu peux
écrire
int f(a,b) int a,b; { return f(a) + fp(b); }
En news:48e6139f$0$10248$426a74cc@news.free.fr, candide va escriure:
tel jugement du tribunal de Becon-les-Bruyères
Il n'y a pas de Tribunal à Bécon.
Non, il y a des différences entre les deux. La plus évidente
est que tu peux
écrire
int f(a,b) int a,b; { return f(a) + fp(b); }
En news:48e6139f$0$10248$, candide va escriure:tel jugement du tribunal de Becon-les-Bruyères
Il n'y a pas de Tribunal à Bécon.
Non, il y a des différences entre les deux. La plus évidente
est que tu peux
écrire
int f(a,b) int a,b; { return f(a) + fp(b); }