Bonjour,
Ci-dessous un programme que nous avons recopié en cours. On lui donne un fichier en paramètre dans le main, et il renvoit un fichier compressé. Le taux de compression est médiocre mais sur le principe, ça fonctionne (je l'ai testé).
Cependant je ne comprends absolument pas l'idée générale du programme, l'algorithme quoi. Il est parfaitement obscure ! C'est un peu long, j'espère que ça ne pose pas problème.
La première partie, je la comprends :
A partir de là je ne comprends plus rien :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 #include <stdio.h> int scanbin (char *ch) { int i, k=0; for (i=strlen(ch)-1; i>=0; i--) k+=(ch[i]=='0')?0:1<<i; return k; } void initialisation (int tab[], int taille) { int i; for (i=0; i<taille; i++) tab[i]=0; } struct arbre { unsigned char c; int nboccur, parent, droite, gauche; }; main(int argc, char *argv[]) { int stat[256]; int ntot=0, i, j=0, k=0, index, pac[256], m, lg[256], mask, a=0, b=0, nbout=0, nbtot=0, l=0; char fname[40], code[32], fnameout[40]; unsigned char c; struct arbre *deb; FILE *in, *out; initialisation( stat, 256); printf ("\nEntrez le nom du fichier : "); scanf ("%s",fname); printf ("\nEntrez le nom du fichier de sortie: "); scanf ("%s",fnameout); if ((in=fopen (fname,"rb"))==NULL) { printf ("Erreur ouverture %s",fname); exit(1); } while(1) { c=fgetc(in); if (feof(in)) break; nbtot++; stat[c]++; } for (i=0; i<256; i++) if( stat[i] ) j++; deb= (struct arbre*) malloc (j*2*sizeof(struct arbre)); for (i=0; i<2*j; i++) { deb[i].nboccur=0; deb[i].parent=0; deb[i].droite=0; deb[i].gauche=0; } for (i=0; i<256; i++) if (stat[i]) { deb[k].c=i; deb[k].nboccur=stat[i]; k++; } k=0;
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 while (k<j) { int occ=nbtot; for( i=0; i<j+k; i++) if (!deb[i].parent) if (deb[i].nboccur<occ) { index=i; occ=deb[i].nboccur; } deb[index].parent=k+j; deb[k+j].gauche=index; deb[k+j].nboccur+=deb[index].nboccur; occ=nbtot; for( i=0; i<j+k; i++) if (!deb[i].parent) if (deb[i].nboccur<occ) { index=i; occ=deb[i].nboccur; } deb[index].parent=k+j; deb[k+j].droite=index; deb[k+j].nboccur+=deb[index].nboccur; k++; } int nbs=j+k; for (i=0; i<j; i++) { m=i; for (k=0; k<32; k++) code[k]=0; int r=0; while(1) { k=deb[m].parent; if(!k) break; if (deb[k].droite==m) code[r]='0'; else code[r]='1'; m=k; r++; } pac[ deb[i].c ]=scanbin(code); lg[ deb[i].c ]=strlen(code); } out=fopen (fnameout,"wb"); if (out==NULL) exit(1); fwrite(&nbtot, sizeof(int), 1, out); fwrite(&nbs, sizeof(int), 1, out); fwrite(deb, sizeof(struct arbre), k, out); nbout=0; fseek(in, 0, SEEK_SET); a=0; b=0; while(1) { c=fgetc(in); mask=1<<(lg[c]-1); while(mask) { if ( pac[c]&mask ) a+=1; a<<=1; mask>>=1; b++; if(b==32) { fwrite( &a, sizeof(int), 1, out); b=0; a=0; } } nbout++; if(nbout==nbtot) break; } fclose(in); fclose(out); }
Partager