Bonjour,

J'ai un petit souci avec le code que j'ai pondu. Voici le problème: je bosse sur un projet qui implique de gérer un dictionnaire, sous forme de fichier texte qui fait environ 500k lignes. Le problème, c'est que certaines lignes sont mal classées suivant l'ordre de la fonction strcmp(); ce qui implique qu'il faut trier le dictionnaire avant de l'utiliser. J'ai implémenté un "tri à bulles" ( http://fr.wikipedia.org/wiki/Tri_%C3%A0_bulles ) sur le fichier texte, mais comme vous devez vous douter, la complexité de l'algo étant en O(n²), pour un fichier de 500k lignes il faut environ une semaine d'exécution non-stop. Donc pas bon.

Du coup, je bosse sur un autre algo de tri, "tri fusion" ( http://fr.wikipedia.org/wiki/Tri_fusion ) qui, lui, est en O(n*log(n)). Le problème, c'est l'implémentation, car il s'agit d'un fichier texte... J'ai donc tenté la solution consistant à le copier dans un char** et ensuite faire tourner l'algo dessus (chaque ligne du dico étant affectée à une ligne du tableau donc), mais comme je ne suis pas super à l'aise avec ce format de données, mon prog me fait un SegFault sans que je sache trop pourquoi. Voici mon code (les quelques printf sont là pour essayer de traquer le bug):




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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
 
 
 
 
/*
Les deux listes sont déjà triées dans l'ordre croissant de strcmp()
*/
char** fusionListes(char* liste1[], char* liste2[])
{
	int i = 0;
	int j = 0;
	int k = 0;
	char** tableau = (char**)malloc(sizeof(tableau));
 
	while ((liste1[i] != NULL) || (liste2[j] != NULL))
	{
		if (strcmp(liste1[i], liste2[j]) == 1)
		{
			tableau[k] = liste2[j];
			j++;
		}
		if (strcmp(liste1[i], liste2[j]) == -1)
		{
			tableau[k] = liste1[i];
			i++;
		}
		if (strcmp(liste1[i], liste2[j]) == 0)	
		{
			tableau[k] = liste1[i];
			k++;
			tableau[k] = liste2[j];
		}
		k++;
	}
	return tableau;
}
 
 
 
 
 
 
 
 
 
 
 
/*
Tri fusion (récursif): http://fr.wikipedia.org/wiki/Tri_fusion#Tri.2C_proc.C3.A9dure_compl.C3.A8te
*/
char** triFusion(char** tableau, long int length)
{
	char* aux = (char*)malloc(200);
 
	if (length == 2)
	{
		if (strcmp(tableau[0], tableau[1]) > 0)
		{
			strcpy(aux, tableau[1]);
			strcpy(tableau[1], tableau[0]);
			strcpy(tableau[0], aux);
		}
	}
	else
	{
		int i = 0;
		int half = (int)(length/2)+1;
		char* tableau1[half];
		char* tableau2[half];
		printf("avant le premier for\n");
		for (i = 0; i < half; i++)
		{
			printf("liste1[%d] = %s, liste[%d] = %s\n", i, tableau1[i], i, tableau[i]);
			strcpy(tableau1[i], tableau[i]);
			printf("liste1[0] = %s", tableau1[0]);
		}
		printf("avant le deuxième for\n");
		for (i = half; i < length; i++)
		{
			strcpy(tableau2[i], tableau[i]);
		}
		printf("avant l'appel récursif de triFusion\n");
		tableau = fusionListes(triFusion(tableau1, half), triFusion(tableau2, half));
	}
	return tableau;
}
 
 
 
 
 
 
 
 
 
 
 
int main(int argc, char** argv)
{	
	if (argc != 2)
	{
		printf("ERREUR: argument doit etre du type \"fichier en entree\".\n");
		return 0;
	}
 
	int i = 0;
	long int nombre_lignes = 1;
	char ligne_lue[200];
	char c[0];
 
	char* resultat = (char*)malloc(10*sizeof(*resultat));
	strcpy(resultat, argv[1]);
	strcat(resultat, "sorted.txt");
 
	FILE* fichier = NULL;
	fichier = fopen(argv[1], "r");
 
	while ((c[0] = fgetc(fichier)) != EOF)
	{
		if (c[0] == '\n') 
		{
			nombre_lignes++;
		}
	}
	fseek(fichier, 0, SEEK_SET);
	printf("le fichier %s contient %d lignes! c'est cool\n", argv[1], (int)nombre_lignes);
 
	char** tableau = (char**)malloc(sizeof(tableau));
 
	while (fgets(ligne_lue, 200, fichier) != NULL)
	{
		printf("tableau[0] = %s, ligne_lue = %s", tableau[0], ligne_lue);
		printf("dans le while...\n");
		strcpy(tableau[i], ligne_lue);
		printf("i = %d, tableau[i] = %s, ligne_lue = %s", i, tableau[i], ligne_lue);
		i++;
	}
 
	printf("nombre_lignes = %d\n", (int)nombre_lignes);
	char** liste = triFusion(tableau, nombre_lignes);
	printf("après appel à triFusion\n");
	FILE* output_fichier = NULL;
	output_fichier = fopen(resultat, "w");
 
	for (i = 0; i < nombre_lignes; i++)
	{
		fprintf(fichier, "%s", liste[i]);
	}
 
	printf("tri terminé! :'-)\n");	
 
	fclose(fichier);
	fclose(output_fichier);
	return 0;
}


Si une âme charitable pouvait me conseiller, ce serait super!