Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
Loading items

Target

Select target project
  • algorithmique/cours
  • aurelien.boyer/cours
  • jeremy.meissner/cours
  • radhwan.hassine/cours
  • yassin.elhakoun/cours-algo
  • gaspard.legouic/cours
  • joachim.bach/cours
  • gabriel.marinoja/algo-cours
  • loic.lavorel/cours
  • iliya.saroukha/cours
  • costanti.volta/cours
  • jacquesw.ndoumben/cours
12 results
Select Git revision
Loading items
Show changes
Commits on Source (703)
Showing
with 1315 additions and 3 deletions
*.o
*.xopp*
slides/package-lock.json
slides/package.json
slides/.vscode/settings.json
.vscode/settings.json
slides/node_modules/.package-lock.json
image: omalaspinas/pandoc:latest
image: omalaspinas/c_pandoc:latest
variables:
GIT_SUBMODULE_STRATEGY: recursive
......@@ -9,8 +9,8 @@ before_script:
## Install ssh-agent if not already installed, it is required by Docker.
## (change apt-get to yum if you use an RPM-based image)
##
- 'which ssh-agent || (pacman -S --noconfirm openssh)'
- 'which rsync || (pacman -S --noconfirm rsync)'
- 'which ssh-agent || (apk add --update openssh-client)'
- 'which rsync || (apk add --update rsync)'
##
......
# Remerciements et contributions
Merci aux contributeurs suivants pour leurs efforts (dans un ordre alphabétique):
* P. Albuquerque
* J. Bach
* A. Boyer
* M. Corboz
* M. Divià
* Y. El Hakouni
* A. Escribano
* P. Kunzli
* G. Legouic
* G. Marino Jarrin
* H. Radhwan
* I. Saroukhanian
* C. Volta
*.o
main
CC=gcc
CFLAGS=-g -std=gnu11 -Wall -Wextra -pedantic -fsanitize=address -fsanitize=leak -fsanitize=undefined
LDFLAGS=-fsanitize=address -fsanitize=leak -fsanitize=undefined
SOURCES=$(wildcard *.c)
OBJECTS=$(SOURCES:.c=.o)
TARGET = main
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $^ -o $@ $(LDFLAGS)
hm.c: hm.h
.PHONY = clean
clean:
rm -f $(OBJECTS) $(TARGET)
#include "hm.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int hash(char *key, int capacity) {
int h = 0;
for (size_t i = 0; i < strlen(key); ++i) {
h = (h + key[i] * 43) % capacity;
}
return h;
}
static int rehash(char *key) {
return 1;
}
static int find_index(hm h, char *key) {
int i = hash(key, h.capacity);
int init = i;
while (h.table[i].state != empty &&
strncmp(h.table[i].key, key, MAX_LEN) != 0) {
i = (i + rehash(key)) % h.capacity;
if (i == init) {
return -1;
}
}
return i;
}
void hm_init(hm *h, int capacity) {
h->table = malloc(capacity * sizeof(cell_t));
h->capacity = capacity;
for (int i = 0; i < h->capacity; ++i) {
h->table[i].state = empty;
}
}
void hm_destroy(hm *h) {
free(h->table);
h->table = NULL;
h->capacity = -1;
}
bool hm_set(hm *h, char *key, char *value) {
int i = hash(key, h->capacity);
int init = i;
while (h->table[i].state == occupied &&
strncmp(h->table[i].key, key, MAX_LEN) != 0) {
i = (i + rehash(key)) % h->capacity;
if (i == init) {
return false;
}
}
if (strncpy(h->table[i].key, key, MAX_LEN) == NULL) {
return false;
};
if (strncpy(h->table[i].value, value, MAX_LEN) == NULL) {
return false;
};
h->table[i].state = occupied;
return true;
}
char *hm_get(hm h, char *key) {
int i = find_index(h, key);
return (i >= 0 && h.table[i].state == occupied) ? h.table[i].value : NULL;
}
char *hm_remove(hm *h, char *key) {
int i = find_index(*h, key);
if (i >= 0 && h->table[i].state == occupied) {
h->table[i].state = deleted;
return h->table[i].value;
} else {
return NULL;
}
}
void hm_print(hm h) {
for (int i = 0; i < h.capacity; ++i) {
if (h.table[i].state == occupied) {
printf("[%d], key: %s, value: %s\n", i, h.table[i].key,
h.table[i].value);
} else {
printf("[%d], key: none, value: none\n", i);
}
}
}
#ifndef _HM_H_
#define _HM_H_
#include <stdbool.h>
#define MAX_LEN 80
typedef enum { empty, occupied, deleted } state_t;
typedef struct _cell_t {
state_t state;
char key[MAX_LEN];
char value[MAX_LEN];
} cell_t;
typedef struct _hm {
int capacity;
cell_t *table;
} hm;
void hm_init(hm *h, int capacity);
void hm_destroy(hm *h);
bool hm_set(hm *h, char *key, char *value);
char *hm_get(hm h, char *key);
char *hm_remove(hm *h, char *key);
void hm_print(hm h);
#endif
#include "hm.h"
#include <stdio.h>
int main() {
hm h;
hm_init(&h, 5);
for (int i = 0; i < 7; ++i) {
char key[MAX_LEN], value[MAX_LEN];
printf("Enter key please:\n");
scanf("%s", key);
printf("Enter value please:\n");
scanf("%s", value);
hm_set(&h, key, value);
hm_print(h);
}
printf("DELETE VALUES!\n");
for (int i = 0; i < 2; ++i) {
char key[MAX_LEN];
printf("Enter key please:\n");
scanf("%s", key);
printf("Value: ");
char *value = hm_remove(&h, key);
if (value == NULL) {
printf("Key not found.\n");
} else {
printf("Value is %s.\n", value);
}
hm_print(h);
}
printf("SEARCH VALUES!\n");
for (int i = 0; i < 2; ++i) {
char key[MAX_LEN];
printf("Enter key please:\n");
scanf("%s", key);
printf("Value: ");
char *value = hm_get(h, key);
if (value == NULL) {
printf("Key not found.\n");
} else {
printf("Value is %s.\n", value);
}
}
hm_destroy(&h);
/* for (int i = 0; i < 6; ++i) { */
/* scanf("%s", key); */
/* scanf("%s", value); */
/* } */
}
@charset "UTF-8";
/* Import ET Book styles
adapted from https://github.com/edwardtufte/et-book/blob/gh-pages/et-book.css */
@font-face {
font-family: "et-book";
src: url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.eot");
src: url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.eot?#iefix") format("embedded-opentype"), url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.woff") format("woff"), url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.ttf") format("truetype"), url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.svg#etbookromanosf") format("svg");
font-weight: normal;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "et-book";
src: url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.eot");
src: url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.eot?#iefix") format("embedded-opentype"), url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.woff") format("woff"), url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.ttf") format("truetype"), url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.svg#etbookromanosf") format("svg");
font-weight: normal;
font-style: italic;
font-display: swap;
}
@font-face {
font-family: "et-book";
src: url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.eot");
src: url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.eot?#iefix") format("embedded-opentype"), url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.woff") format("woff"), url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.ttf") format("truetype"), url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.svg#etbookromanosf") format("svg");
font-weight: bold;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "et-book-roman-old-style";
src: url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.eot");
src: url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.eot?#iefix") format("embedded-opentype"), url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.woff") format("woff"), url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.ttf") format("truetype"), url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.svg#etbookromanosf") format("svg");
font-weight: normal;
font-style: normal;
font-display: swap;
}
/* Tufte CSS styles */
html {
font-size: 15px;
}
body {
width: 87.5%;
margin-left: auto;
margin-right: auto;
padding-left: 12.5%;
font-family: et-book, Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;
background-color: #fffff8;
color: #111;
max-width: 1400px;
counter-reset: sidenote-counter;
}
h1 {
font-weight: 400;
margin-top: 4rem;
margin-bottom: 1.5rem;
font-size: 3.2rem;
line-height: 1;
}
h2 {
font-style: italic;
font-weight: 400;
margin-top: 2.1rem;
margin-bottom: 1.4rem;
font-size: 2.2rem;
line-height: 1;
}
h3 {
font-style: italic;
font-weight: 400;
font-size: 1.7rem;
margin-top: 2rem;
margin-bottom: 1.4rem;
line-height: 1;
}
hr {
display: block;
height: 1px;
width: 55%;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
p.subtitle {
font-style: italic;
margin-top: 1rem;
margin-bottom: 1rem;
font-size: 1.8rem;
display: block;
line-height: 1;
}
.numeral {
font-family: et-book-roman-old-style;
}
.danger {
color: red;
}
article {
padding: 5rem 0rem;
}
section {
padding-top: 1rem;
padding-bottom: 1rem;
}
p,
dl,
ol,
ul {
font-size: 1.4rem;
line-height: 2rem;
}
p {
margin-top: 1.4rem;
margin-bottom: 1.4rem;
padding-right: 0;
vertical-align: baseline;
}
/* Chapter Epigraphs */
div.epigraph {
margin: 5em 0;
}
div.epigraph > blockquote {
margin-top: 3em;
margin-bottom: 3em;
}
div.epigraph > blockquote,
div.epigraph > blockquote > p {
font-style: italic;
}
div.epigraph > blockquote > footer {
font-style: normal;
}
div.epigraph > blockquote > footer > cite {
font-style: italic;
}
/* end chapter epigraphs styles */
blockquote {
font-size: 1.4rem;
}
blockquote p {
width: 55%;
margin-right: 40px;
}
blockquote footer {
width: 55%;
font-size: 1.1rem;
text-align: right;
}
section > p,
section > footer,
section > table {
width: 55%;
}
/* 50 + 5 == 55, to be the same width as paragraph */
section > dl,
section > ol,
section > ul {
width: 50%;
-webkit-padding-start: 5%;
}
dt:not(:first-child),
li:not(:first-child) {
margin-top: 0.25rem;
}
figure {
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
max-width: 55%;
-webkit-margin-start: 0;
-webkit-margin-end: 0;
margin: 0 0 3em 0;
}
figcaption {
float: right;
clear: right;
margin-top: 0;
margin-bottom: 0;
font-size: 1.1rem;
line-height: 1.6;
vertical-align: baseline;
position: relative;
max-width: 40%;
}
figure.fullwidth figcaption {
margin-right: 24%;
}
/* Links: replicate underline that clears descenders */
a:link,
a:visited {
color: inherit;
}
.no-tufte-underline:link {
background: unset;
text-shadow: unset;
}
a:link, .tufte-underline, .hover-tufte-underline:hover {
text-decoration: none;
background: -webkit-linear-gradient(#fffff8, #fffff8), -webkit-linear-gradient(#fffff8, #fffff8), -webkit-linear-gradient(currentColor, currentColor);
background: linear-gradient(#fffff8, #fffff8), linear-gradient(#fffff8, #fffff8), linear-gradient(currentColor, currentColor);
-webkit-background-size: 0.05em 1px, 0.05em 1px, 1px 1px;
-moz-background-size: 0.05em 1px, 0.05em 1px, 1px 1px;
background-size: 0.05em 1px, 0.05em 1px, 1px 1px;
background-repeat: no-repeat, no-repeat, repeat-x;
text-shadow: 0.03em 0 #fffff8, -0.03em 0 #fffff8, 0 0.03em #fffff8, 0 -0.03em #fffff8, 0.06em 0 #fffff8, -0.06em 0 #fffff8, 0.09em 0 #fffff8, -0.09em 0 #fffff8, 0.12em 0 #fffff8, -0.12em 0 #fffff8, 0.15em 0 #fffff8, -0.15em 0 #fffff8;
background-position: 0% 93%, 100% 93%, 0% 93%;
}
@media screen and (-webkit-min-device-pixel-ratio: 0) {
a:link, .tufte-underline, .hover-tufte-underline:hover {
background-position-y: 87%, 87%, 87%;
}
}
a:link::selection,
a:link::-moz-selection {
text-shadow: 0.03em 0 #b4d5fe, -0.03em 0 #b4d5fe, 0 0.03em #b4d5fe, 0 -0.03em #b4d5fe, 0.06em 0 #b4d5fe, -0.06em 0 #b4d5fe, 0.09em 0 #b4d5fe, -0.09em 0 #b4d5fe, 0.12em 0 #b4d5fe, -0.12em 0 #b4d5fe, 0.15em 0 #b4d5fe, -0.15em 0 #b4d5fe;
background: #b4d5fe;
}
/* Sidenotes, margin notes, figures, captions */
img {
max-width: 100%;
}
.sidenote,
.marginnote {
float: right;
clear: right;
margin-right: -60%;
width: 50%;
margin-top: 0.3rem;
margin-bottom: 0;
font-size: 1.1rem;
line-height: 1.3;
vertical-align: baseline;
position: relative;
}
.sidenote-number {
counter-increment: sidenote-counter;
}
.sidenote-number:after,
.sidenote:before {
font-family: et-book-roman-old-style;
position: relative;
vertical-align: baseline;
}
.sidenote-number:after {
content: counter(sidenote-counter);
font-size: 1rem;
top: -0.5rem;
left: 0.1rem;
}
.sidenote:before {
content: counter(sidenote-counter) " ";
font-size: 1rem;
top: -0.5rem;
}
blockquote .sidenote,
blockquote .marginnote {
margin-right: -82%;
min-width: 59%;
text-align: left;
}
div.fullwidth,
table.fullwidth {
width: 100%;
}
div.table-wrapper {
overflow-x: auto;
font-family: "Trebuchet MS", "Gill Sans", "Gill Sans MT", sans-serif;
}
.sans {
font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
letter-spacing: .03em;
}
code, pre > code {
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 1.0rem;
line-height: 1.42;
-webkit-text-size-adjust: 100%; /* Prevent adjustments of font size after orientation changes in iOS. See https://github.com/edwardtufte/tufte-css/issues/81#issuecomment-261953409 */
}
.sans > code {
font-size: 1.2rem;
}
h1 > code,
h2 > code,
h3 > code {
font-size: 0.80em;
}
.marginnote > code,
.sidenote > code {
font-size: 1rem;
}
pre > code {
font-size: 0.9rem;
width: 52.5%;
margin-left: 2.5%;
overflow-x: auto;
display: block;
}
pre.fullwidth > code {
width: 90%;
}
.fullwidth {
max-width: 90%;
clear:both;
}
span.newthought {
font-variant: small-caps;
font-size: 1.2em;
}
input.margin-toggle {
display: none;
}
label.sidenote-number {
display: inline;
}
label.margin-toggle:not(.sidenote-number) {
display: none;
}
.iframe-wrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9 */
padding-top: 25px;
height: 0;
}
.iframe-wrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
@media (max-width: 760px) {
body {
width: 84%;
padding-left: 8%;
padding-right: 8%;
}
hr,
section > p,
section > footer,
section > table {
width: 100%;
}
pre > code {
width: 97%;
}
section > dl,
section > ol,
section > ul {
width: 90%;
}
figure {
max-width: 90%;
}
figcaption,
figure.fullwidth figcaption {
margin-right: 0%;
max-width: none;
}
blockquote {
margin-left: 1.5em;
margin-right: 0em;
}
blockquote p,
blockquote footer {
width: 100%;
}
label.margin-toggle:not(.sidenote-number) {
display: inline;
}
.sidenote,
.marginnote {
display: none;
}
.margin-toggle:checked + .sidenote,
.margin-toggle:checked + .marginnote {
display: block;
float: left;
left: 1rem;
clear: both;
width: 95%;
margin: 1rem 2.5%;
vertical-align: baseline;
position: relative;
}
label {
cursor: pointer;
}
div.table-wrapper,
table {
width: 85%;
}
img {
width: 100%;
}
}
main
*.o
CC=gcc
CFLAGS=-g -std=gnu11 -Wall -Wextra -pedantic -fsanitize=address -fsanitize=leak -fsanitize=undefined
LDFLAGS=-fsanitize=address -fsanitize=leak -fsanitize=undefined
SOURCES=$(wildcard *.c)
OBJECTS=$(SOURCES:.c=.o)
TARGET = main
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $^ -o $@ $(LDFLAGS)
hashmap.c: hashmap.h
.PHONY = clean
clean:
rm -f $(OBJECTS) $(TARGET)
#include "hm.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static bool is_not_allocated(hm h) {
return (h.table == NULL || h.capacity < 1 || h.size < 0);
}
static size_t hash(hm h, char key[MAX_LEN]) {
int index = 0;
for (size_t i = 0; i < strlen(key); ++i) {
index = (index + key[i] * 43) % h.capacity;
}
return index;
}
static int rehash(char *key) {
return 1;
}
static bool search_condition(hm h, char key[MAX_LEN], int index) {
return strncmp(h.table[index].key, key, MAX_LEN) == 0 &&
h.table[index].state == occupied;
}
static bool set_condition(hm h, char key[MAX_LEN], int index) {
return search_condition(h, key, index) || h.table[index].state != occupied;
}
static int find_index(
hm h, char key[MAX_LEN], bool (*condition)(hm, char[], int)) {
int try = 0;
int index = hash(h, key);
while (try < h.capacity) {
if (condition(h, key, index)) {
return index;
}
index = (index + rehash(key)) % h.capacity;
try += 1;
}
return -1;
}
static bool is_empty(hm h) {
return h.size == 0;
}
void hm_init(hm *h, int capacity) {
h->capacity = capacity;
h->size = 0;
h->table = malloc(h->capacity * sizeof(*h->table));
for (int i = 0; i < h->capacity; ++i) {
h->table[i].state = empty;
}
}
void hm_destroy(hm *h) {
h->capacity = -1;
h->size = -1;
free(h->table);
h->table = NULL;
}
bool hm_set(hm *h, char *key, char *value) {
if (is_not_allocated(*h)) {
return false;
}
int index = find_index(*h, key, set_condition);
if (index < 0) {
return false;
}
/* printf("%d\n", index); */
strncpy(h->table[index].value, value, MAX_LEN);
strncpy(h->table[index].key, key, MAX_LEN);
h->table[index].state = occupied;
h->size += 1;
return true;
}
bool hm_get(hm h, char *key, char *value) {
int index = find_index(h, key, search_condition);
if (index >= 0) {
strncpy(value, h.table[index].value, MAX_LEN);
return true;
}
return false;
}
bool hm_remove(hm *h, char *key, char *value) {
int index = find_index(*h, key, search_condition);
if (index >= 0) {
h->table[index].state = deleted;
strncpy(value, h->table[index].value, MAX_LEN);
h->size -= 1;
return true;
}
return false;
}
bool hm_search(hm h, char *key) {
int index = find_index(h, key, search_condition);
return (index >= 0);
}
void hm_print(hm h) {
if (is_not_allocated(h)) {
printf("Well this hashmap is not allocated n00b.\n");
}
if (is_empty(h)) {
printf("The hashmap is empty.\n");
}
for (int i = 0; i < h.capacity; ++i) {
if (h.table[i].state == occupied) {
printf("index: %d, key: %s, value: %s\n", i, h.table[i].key,
h.table[i].value);
} else {
printf("index: %d, key: {none}, value: {none}\n", i);
}
}
}
#ifndef _HM_H_
#define _HM_H_
#include <stdbool.h>
#define MAX_LEN 80
typedef enum { empty, occupied, deleted } state_t;
typedef struct _cell_t {
char key[MAX_LEN];
char value[MAX_LEN];
state_t state;
} cell_t;
typedef struct _hm {
cell_t *table;
int capacity;
int size;
} hm;
void hm_init(hm *h, int capacity);
void hm_destroy(hm *h);
bool hm_set(hm *h, char *key, char *value);
bool hm_get(hm h, char *key, char *value);
bool hm_remove(hm *h, char *key, char *value);
bool hm_search(hm h, char *key);
void hm_print(hm h);
#endif
#include "hm.h"
#include <stdio.h>
int main() {
char key[80], value[80];
hm h;
hm_init(&h, 5);
for (int i = 0; i < 6; ++i) {
scanf("%s", key);
scanf("%s", value);
hm_set(&h, key, value);
hm_print(h);
if (hm_search(h, "orestis")) {
printf("orestis found.\n");
}
if (hm_remove(&h, "orestis", value)) {
printf("orestis removed: %s.\n", value);
}
}
hm_destroy(&h);
}
*.log
*.aux
*.pdf
*.dvi
*.eps
# Algorithmes et structures de données
# Deux applications des piles
*****
## La transformation infixe $\Leftarrow$ postfixe
Exemples:
| Expression infixe | | Expression postfixe |
|-----------------------|------------------|---------------------|
| A + B * C | transformé en | A B C * + |
| A + (B / C – D ^ E ) | transformé en | A B C / D E ^ – + |
A chaque opérateur, on associe une priorité, par exemple:
| Opérateur | Priorité |
|-----------|----------|
| ^ | 3 |
| *, / | 2 |
| +, - | 1 |
L'algorithme utilise une pile dans laquelle on stocke les opérateurs et les parenthèses ouvertes
rencontrées dans l'expression.
Les étapes sont les suivantes :
1. Examiner le prochain caractère dans l'expression donnée.
2. Si c'est un opérande, le mettre directement dans l'expression du résultat.
3. Si c'est une parenthèse ouverte, la mettre dans la pile avec la priorité zéro.
4. Si c'est un opérateur, comparer sa priorité avec celle de l'élément au sommet de la pile:
* Si la priorité de l'opérateur est plus grande que l'opérateur du sommet de la pile, empiler ce nouvel opérateur.
* Sinon prendre l'opérateur du sommet de la pile, le mettre dans l'expression du résultat et répéter la comparaison avec le nouveau sommet de la pile, jusqu'à ce qu'un opérateur de priorité inférieure à celle de l'opérateur de l'expression apparaisse au sommet de la pile ou jusqu'à ce que la pile soit vide.
5. Si c'est une parenthèse fermée, enlever de la pile les opérateurs et les placer dans l'expression du résultat jusqu'à ce qu'une parenthèse ouverte apparaisse au sommet de la pile, se défaire de cette parenthèse.
6. Si l'expression donnée est vide, enlever de la pile les opérateurs restants et les placer dans l'expression du résultat.
La table ci-dessous montre la réalisation d'une transformation infixe - postfixe sur une expression algébrique (supposée syntaxiquement correcte):
![Exemple de transformation infixe-postfixe](./figures/fig_transf_infixe_postfixe.png)
**Remarque:** On utilise aussi d'autres structures de données pour traiter ce problème. Entre autres les arbres.
## L'évaluation d'une expression en notation postfixée
La manière la plus simple de procéder est d'utiliser une pile contenant à chaque instant les valeurs des opérandes déjà calculés.
Dans une expression donnée sous forme postfixée, chaque opérateur porte sur les opérandes qui le précédent immédiatement, ceux ci doivent toujours se trouver en tête de pile au moment de l'opération. Le résultat d'une opération est un nouvel opérande qui est remis au sommet de la pile pour la suite de l'évaluation.
Les règles d'évaluation sont les suivantes:
* la valeur d'un opérande est toujours empilée.
* Un opérateur s'applique toujours aux 2 opérandes en tête de pile.
* Le résultat de l'opération est remis en tête de pile.
Exemple:
Soit l'expression postfixe à évaluer: A B C + * D -
| Caractères lus | Pile des opérandes (nombres) |
|----------------|------------------------------|
| A | A |
| B | A, B |
| C | A, B, C |
| + | A, B+C |
| * | A*(B+C) |
| D | A*(B+C), D |
| A | *(B+C)-D |
La pile contient finalement la valeur de l'expression.
Ce traitement exige naturellement que l'expression à évaluer soit syntaxiquement correcte.
\ No newline at end of file
# Algorithmes et structures de données
# Structure de pile
*****
## 1. Définition
Une pile est une structure de données dans laquelle la dernière information entrée, est la première à ressortir (en anglais : LIFO, Last In First Out)
On envisage deux types d'implémentation de piles:
1. l'une à capacité limitée (piles dénommées statiques);
2. l'autre à capacité « infinie » (piles dénommées dynamiques dont la capacité limite dépend en réalité de la mémoire disponible).
## 2. Spécification de la structure
Le type des éléments qu'on empile, n'étant pas précisé, on parle de spécification générique.
Les opérations possibles sur une pile en définissent l'interface :
* Opérations de manipulation
* Empiler un nouvel élément sur la pile
* Dépiler l'élément au sommet de la pile (i.e. le dernier élément introduit)
* Fonctions de consultation
* Lire l'élément au sommet de la pile
* Tester si la pile est vide
* Tester si la pile a atteint la capacité maximale, seulement dans le cas d'une pile statique
* L'interface de la pile est l'ensemble des fonctionnalités offertes à l'utilisateur pour interagir avec une pile
## 3. Quelques applications des piles
* Gérer les mécanismes internes de mise en œuvre de la récursivité
* Traiter les structures imbriquées
* Implémenter les machines abstraites
* Passer les paramètres aux procédures
* Sauver l'état d'un processus
\ No newline at end of file
# Algorithmes et structures de données
# Structure de file d'attente
*****
## 1. Définition
Une file d'attente ou queue est une structure de données dans laquelle la première information entrée est la première à ressortir (en anglais : FIFO, First In First Out)
On considère ici une implémentation de queue dynamique et donc à capacité « infinie » (dépend en réalité de la mémoire disponible).
## 2. Spécification de la structure
Si le type des éléments qu'on insère, n'est pas précisé, on parle de spécification générique.
Les opérations possibles sur une file d'attente (ou queue) en définissent l'interface :
* Opérations de manipulation
* Créer une liste vide
* Détruire une liste
* Insérer un nouvel élément en queue de la file d'attente
* Extraire un élément en tête de la file d'attente (i.e. le premier élément introduit)
*
* Fonctions de consultation
* Lire l'élément en tête de la file d'attente
* Lire l'élément en queue de la file d'attente
* Tester si la file d'attente est vide
L'interface de la file d'attente est l'ensemble des fonctionnalités offertes à l'utilisateur pour interagir
avec celle-ci.
## 3. Structure de file d'attente
On considère une liste chaînée d'articles avec deux pointeurs de tête et de queue. Chaque article comportera un champ pour stocker les valeurs dans cette liste et un champ contenant une variable de type accès pour assurer le chaînage. On considère à titre d'exemple le cas de valeurs entières.
Schématiquement:
![Illustration d'une file d'attente](./figures/fig_queue_representation.png)
L'accès à la file d'attente se fera par les pointeurs de tête et de queue.
Une telle file d'attente basée sur une liste chaînée sera déclarée par exemple sous la forme suivante:
```C
struct _element { // Elément de liste
int data;
struct _element* next;
} element;
struct _queue { // File d'attente:
element* tete; // tête de file d'attente
element* debut; // queue de file d'attente
}
```
## 4. Implémentation des fonctionnalité d'une file d'attente
### a) Consultations
On considère la fonction queue_est_vide qui teste si la file d'attente est vide et les fonctions `queue_tete` et `queue_debut` qui retournent l'élément en tête, respectivement en queue, de la file d'attente.
```C
bool queue_est_vide(queue fa) {
return (NULL == fa.tete && NULL == fa.debut);
}
int queue_tete(queue fa) {
assert(!queue_est_vide(fa));
return fa.tete­>data;
}
int queue_debut(queue fa) {
assert(!queue_est_vide(fa));
return fa.debut­>data;
}
```
### b) Manipulations
#### Insertion en queue de file d'attente
Voici l'entête de la fonction: `void queue_inserer(queue* fa,int val);`
Il faut considérer plusieurs cas:
* La file d'attente est vide
![Insertion dans une file d'attente vide](./figures/fig_empty_queue_insert.png)
* L'insertion se fait en queue d'une file d'attente non vide
![Insertion dans une file d'attente non-vide](./figures/fig_non_empty_queue_insert.png)
#### Extraction en tête de file d'attente
Voici l'entête de la procédure: `int queue_extraire(queue* fa);`
On commence par récupérer, la valeur en tête de file d'attente via l'appel `queue_tete(*fa);`
Puis on met un pointeur temporaire sur l'élément en tête, avant de déplacer le pointeur de tête sur l'élément suivant.
Finalement, on désalloue la mémoire
![Extraction d'une file d'attente](./figures/fig_queue_extract.png)
Si la file d'attente n'avait qu'un seul élément, alors il faudrait mettre le pointeur `fa-­>debut` à `NULL`.
Dans ce cas, à la suite du point (3), le pointeur `fa-­>tete` se retrouve à `NULL`. On doit donc ajouter l'instruction :
```C
if (NULL == fa­>tete) {
fa­>debut = NULL;
}
```
# Algorithmes et structures de données
# Structure de liste triée
*****
## 1. Définition
On considère une liste chaînée d'articles. Chaque article comportera un champ pour stocker les valeurs
dans la liste et un champ contenant une variable de type pointeur pour assurer le chaînage.
Schématiquement:
![Illustration d'une file d'attente](./figures/fig_queue_representation.png)
La liste est triée pour autant que l'insertion de chaque nouvelle valeur dans la liste maintienne cette
propriété.
L'accès à la liste se fera uniquement par le pointeur lst qui référence le début de la liste.
Une telle liste chaînée sera déclarée par exemple sous la forme suivante:
```C
typedef struct _element { // Elément de liste
int n;
struct _element* suivant;
} element;
typedef element* liste; // Pointeur sur des éléments de liste
```
## 2. Insertion dans une liste triée
Voici l'entête de la procédure : `liste inserer(liste lst,int val);`
Il faut considérer plusieurs cas.
### La liste est vide: `lst == NULL`
![Insertion dans une liste triée vide](./figures/fig_empty_sorted_list_insert.png)
### L'insertion se fait en 1ère position: `val <= lst->n`
Par exemple, pour `val = 1`
![Insertion en 1ère position d'une liste triée](./figures/fig_1st_position_sorted_list_insert.png)
### Les positions autres que la 1ère position
Par exemple, pour `val = 13`
![Insertion aux autres positions d'une liste triée](./figures/fig_other_position_sorted_list_insert.png)
```C
(1) tmp = malloc(sizeof(element));
tmp->n = 13;
```
On déplace un pointeur crt jusqu'à l'élément précédent la position d'insertion de sorte que
```C
crt->n < val <= crt->suivant->n
```
On utilise une boucle:
```C
(2) while (NULL != crt->suivant && val > crt->suivant->n) {
crt = crt->suivant;
}
```
Puis on raccroche l'élément pointé par tmp à la liste
```C
(3) tmp->suivant = crt->suivant;
(4) crt->suivant = tmp;
return lst;
```
## 3. Extraction d'un élément dans une liste triée
Voici l'entête de la procédure : `liste extraire(liste lst,int val);`
Si la liste est vide, on retourne la liste vide.
Ensuite, on déplace deux pointeurs prec et crt à travers la liste jusqu'à ce que : `prec->n < val <= crt->n`
On utilise une boucle:
```C
while (NULL != crt && val > crt->n) {
prec = crt;
crt = crt->suivant;
}
```
Il faut à nouveau considérer plusieurs cas.
### La valeur à retirer est supérieure à la dernière valeur de la liste.
Ceci équivaut à: `crt == NULL` ou `prec->suivant == NULL`
On retourne la liste inchangée.
Par exemple, pour `val = 30`
![Extraction d'une valeur supérieure à la dernière valeur d'une liste triée](./figures/fig_greater_value_sorted_list_extract.png)
### La valeur à retirer n'est pas celle dans l'élément pointé par `crt`.
Ceci équivaut à: `val < crt->n`
On retourne la liste inchangée.
Par exemple, pour `val = 9`
![Extraction d'une valeur pas dans une liste triée (1)](./figures/fig_no_value_sorted_list_extract_1.png)
ou pour val = 1
![Extraction d'une valeur pas dans une liste triée (2)](./figures/fig_no_value_sorted_list_extract_2.png)
### La valeur à retirer est celle dans l'élément pointé par `crt`.
Ceci équivaut à: `val == crt->n`
#### La valeur à retirer est en début de liste.
Ceci équivaut à: `crt == prec`
On doit déplacer la tête de liste : lst = crt->suivant;
Par exemple, pour `val = 3`
![Extraction d'une valeur en début de liste triée ](./figures/fig_1st_element_sorted_list_extract.png)
#### La valeur à retirer n'est pas en début de liste.
On doit raccrocher l'élément pointé par prec à celui suivant `crt`: `prec->suivant = crt->suivant;`
Par exemple, pour `val = 12`
![Extraction d'une valeur pas en début de liste triée](./figures/fig_other_element_sorted_list_extract_1.png)
ou pour `val = 21`
![Extraction d'une valeur pas dans une liste triée (1)](./figures/fig_other_element_sorted_list_extract_2.png)
Finalement, on libère la mémoire de l'élément pointé par `crt`: `free(crt);`
![Extraction d'une valeur pas dans une liste triée (1)](./figures/fig_free_element_sorted_list_extract.png)
## 4. Recherche dans une liste triée
La fonction recherche retourne un pointeur sur l'élément qui contient la valeur recherchée ou un pointeur `NULL` si la valeur est absente de la liste triée.
Voici l'entête de la procédure : `element* recherche(liste lst,int val);`
On considère d'abord la fonction utilitaire `position` qui retourne un pointeur sur l'élément avant la
position d'insertion d'une valeur ou un pointeur `NULL` s'il s'agit de la tête de liste.
```C
element* position(liste lst,int val) {
element* pos = lst;
if (est_vide(lst) || val <= lst->n) {
pos = NULL;
} else {
while (NULL != pos->suivant && val > pos->suivant->n) {
pos = pos->suivant;
}
}
return pos;
}
```
Par exemple, pour val = 1 ou 3
![Recherche d'une valeur en début de liste triée](./figures/fig_1st_element_sorted_list_search.png)
et pour val = 29
![Recherche d'une valeur en fin de liste triée](./figures/fig_last_element_sorted_list_search.png)
et finalement pour val = 10 ou 12
![Recherche d'une valeur en milieu de liste triée](./figures/fig_other_element_sorted_list_search.png)
Ainsi, la fonction de recherche s'écrit simplement :
```C
element* recherche(liste lst,int val) {
element* pos = position(lst,val);
if (est_vide(lst)) {
return NULL;
}
if (NULL == pos && val == lst->n) {
return lst;
} else if (NULL != pos->suivant && val == pos->suivant->n) {
return pos->suivant;
} else {
return NULL;
}
}
```
## Exercice
Ecrire directement la fonction `recherche` sans utiliser la fonction `position`.
Faire les dessins illustrant les différents cas possibles.
lessons/figures/fig_1st_element_sorted_list_extract.png

9.01 KiB