ANALYSEUR DE TEXTE (MAJ V2)

cs_vicenzo Messages postés 178 Date d'inscription mardi 16 août 2005 Statut Membre Dernière intervention 25 août 2010 - 24 sept. 2010 à 08:26
Cyberboy2054 Messages postés 173 Date d'inscription jeudi 20 décembre 2001 Statut Membre Dernière intervention 22 août 2008 - 30 sept. 2010 à 12:02
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/52314-analyseur-de-texte-maj-v2

Cyberboy2054 Messages postés 173 Date d'inscription jeudi 20 décembre 2001 Statut Membre Dernière intervention 22 août 2008
30 sept. 2010 à 12:02
Yop
Maintenant que tu utilise une table, il est inutile de faire un tri à bulle.
Supprime donc la ligne 522 ( triBulle( fileAnalized, 256, ASCIIE_String ); ) dans getFileAnalysis, et regarde le temps d'exécution ;)
sholvaC Messages postés 12 Date d'inscription mercredi 29 avril 2009 Statut Membre Dernière intervention 30 avril 2009
28 sept. 2010 à 00:43
Ah oui en effet, maintenant que vous le dites, c'est plus court, je n'y avais absolument pas pensé. Merci pour cette remarque pertinente. Je tâcherai de m'en souvenir ultérieurement.

Pour les fonction type display, oui on pourrait ne pas mettre un pointeur. Comme les longueurs étaient stockés dans des int*, j'ai juste bêtement continuer ainsi. Y'a pas vraiment de raisons apparentent.
LeFauve42 Messages postés 239 Date d'inscription vendredi 20 octobre 2006 Statut Membre Dernière intervention 20 avril 2009
27 sept. 2010 à 18:53
> generateStringForASCIIEcode() est une fonction qui me permet de générer comme son nom l'indique
> le code C pour déclarer la table ASCIIE dans un tableau de caractères. En effet, je n'avais
> nullement envie de la taper à la main...

Tu veux dire que ca genere ca :
char ASCIIE_String[256]={'\0','\1','\2','\3','\4','\5','\6','\7','\10','\11','\12','\13','\14','\15','\16','\17','\20','\21','\22','\23','\24','\25','\26','\27','\30','\31','\32','\33','\34','\35','\36','\37','\40','\41','\42','\43','\44','\45','\46','\47','\50','\51','\52','\53','\54','\55','\56','\57','\60','\61','\62','\63','\64','\65','\66','\67','\70','\71','\72','\73','\74','\75','\76','\77','\100','\101','\102','\103','\104','\105','\106','\107','\110','\111','\112','\113','\114','\115','\116','\117','\120','\121','\122','\123','\124','\125','\126','\127','\130','\131','\132','\133','\134','\135','\136','\137','\140','\141','\142','\143','\144','\145','\146','\147','\150','\151','\152','\153','\154','\155','\156','\157','\160','\161','\162','\163','\164','\165','\166','\167','\170','\171','\172','\173','\174','\175','\176','\177','\200','\201','\202','\203','\204','\205','\206','\207','\210','\211','\212','\213','\214','\215','\216','\217','\220','\221','\222','\223','\224','\225','\226','\227','\230','\231','\232','\233','\234','\235','\236','\237','\240','\241','\242','\243','\244','\245','\246','\247','\250','\251','\252','\253','\254','\255','\256','\257','\260','\261','\262','\263','\264','\265','\266','\267','\270','\271','\272','\273','\274','\275','\276','\277','\300','\301','\302','\303','\304','\305','\306','\307','\310','\311','\312','\313','\314','\315','\316','\317','\320','\321','\322','\323','\324','\325','\326','\327','\330','\331','\332','\333','\334','\335','\336','\337','\340','\341','\342','\343','\344','\345','\346','\347','\350','\351','\352','\353','\354','\355','\356','\357','\360','\361','\362','\363','\364','\365','\366','\367','\370','\371','\372','\373','\374','\375','\376','\377'};

Alors pour info (desole de l'avoir rate dans mon premier commentaire), cette variable ne sert a rien...
Si tu veux le caracteres "n", il te suffis de caster n en char. Exemple:
- Au lieu de ASCIIE_String[i] tu peux mettre ((char)i)
- Si c'est pour afficher ton char avec printf, tu n'as meme pas besoin de le caster : printf("%c",i) marche directement.

Encore une petite question : pourquoi utilises-tu des int* pour passer les longueurs dans tes fonction display*() ?

Eric
sholvaC Messages postés 12 Date d'inscription mercredi 29 avril 2009 Statut Membre Dernière intervention 30 avril 2009
27 sept. 2010 à 14:52
generateStringForASCIIEcode() est une fonction qui me permet de générer comme son nom l'indique le code C pour déclarer la table ASCIIE dans un tableau de caractères. En effet, je n'avais nullement envie de la taper à la main...

Pour l'affichage du résultat dans la présentation de la source, c'est correctement indenté ce qui n'est pas le cas dans le post...
LeFauve42 Messages postés 239 Date d'inscription vendredi 20 octobre 2006 Statut Membre Dernière intervention 20 avril 2009
27 sept. 2010 à 13:22
Bonjour,

Je suis d'accord avec tout le monde a propos de :
- L'utilisation de realloc qui fragmente la memoire et en plus ici est inutile (si vraiment tu dois t'en servir, essaie de reallouer par blocks d'au moins 8 ou 16 Ko supplementaires, ca reduira la casse, et en plus je crois me souvenir que windows arrondie ses blocks de memoirs aloues a 8 Ko (a verifier).
- Stocker le fichier est inutile : tu lis chaque caractere et tu incrementes son compteur (ce serait peut-etre juste plus lisible d'ecrire table[code]++ au lieu de *(table+code)++ mais c'est une question de gouts). Pense juste a lire plusieurs caracteres a la fois pour aller plus vite (4 ou 8 Ko au moins. Apres 64Ko, le gain de performences devient marginal).

Sinon :
- J'ai du mal a voir ce que tu essaie de faire avec ta fonction generateStringForASCIIEcode(). Est-ce que tu generes un ".c" ? Pour quoi faire ?
- Pour le bubble sort, si tu ne veux pas te casser la tete et vu que tu n'as que 256 valeurs a trier tu peux garder cet algo, mais pour le principe, tu peux ajouter un flag que tu mets lorsque tu permutes deux valeurs. Des ta premiere iteration sans aucune permutation, tu peux arreter le tri car ton tableau est trie (ca fera gagner environ 30% dans la plupart des tableaux). Ici tu ne veras sans doute aucune difference, mais comme tu reutilises ton code, autant avoir une version "plus performante".

Eric
sholvaC Messages postés 12 Date d'inscription mercredi 29 avril 2009 Statut Membre Dernière intervention 30 avril 2009
25 sept. 2010 à 16:57
Ok merci, je n'avais pas du tout pensé à cette astuce, je reprends le code et je poste la source modifiée. Merci pour votre aide et commentaires.
eomer212 Messages postés 13 Date d'inscription lundi 7 février 2011 Statut Membre Dernière intervention 8 février 2011
25 sept. 2010 à 11:54
bingo!
t'as compris.
la, ca va aller vite, le code sera plus court et plus sur.
sholvaC Messages postés 12 Date d'inscription mercredi 29 avril 2009 Statut Membre Dernière intervention 30 avril 2009
25 sept. 2010 à 10:43
Honnêtement, je ne suis toujours pas sûr d'avoir compris. Ce que j'ai compris est ça :

Parcourir le tableau contenant le fichier
Recupérer le caractère courant char current
int code = (int)current // On récupére sa valeur (decimale je crois en convertissant le char en int)
*(table + code)++; // On incrémente directement le compteur du caractere dans la table
Fin du parcours.

Là oui je pense qu'en effet cela risque d'être beaucoup plus rapide ! C'est bien ce que vous expliquiez ?
eomer212 Messages postés 13 Date d'inscription lundi 7 février 2011 Statut Membre Dernière intervention 8 février 2011
24 sept. 2010 à 23:52
justifié, c'est faire en sorte que les chiffres soient alignés pour en faciliter la lecture.
voir printf("%03i",13); tous les chiffres auront 3 numéros.
pour l'algorithme, c'est le nombre d'operation minimaliste qui amene au resultat qui doit etre privilégié.
si tu dois parcourir un fichier, ne le parcours qu'une fois.
si tu dois le lire plusieurs fois, il y a un probleme..
une fois que tu as le contenu du fichier, acceder à une table est plus rapide que tout. tu incremente le compteur correspondant à la valeur que tu as lu.
de plus, si ta table reste limitée, tu n'auras pas de probleme de latence de memoire, optimiser à fond..:)

quand tu as parcouru tout le fichier, ta liste de compteurs contient le nombre de caracteres correspondant dans chaque compteur.
ha, un detail que j'ai oublié de mettre.
par defaut et pat precaution, il vaut mieux initialiser tous les compteurs à 0 pour etre sur, dés le départ.
sholvaC Messages postés 12 Date d'inscription mercredi 29 avril 2009 Statut Membre Dernière intervention 30 avril 2009
24 sept. 2010 à 13:28
Qu'appelez vous le numéro ascii reel justifé ? Sa valeur en base 10 ?
sholvaC Messages postés 12 Date d'inscription mercredi 29 avril 2009 Statut Membre Dernière intervention 30 avril 2009
24 sept. 2010 à 13:21
Oui je suis conscient que le realloc est plus lent que la méthode que vous proposez, c'était juste pour m'entraîner à manier realloc même si je le concède, ce n'était pas le bon exemple.

Je n'ai pas vraiment compris ton algorithme d'indexage mais je vais me renseigner.

Oui et le tri à bulle, j'avoue sa complexité n'est pas la meilleure que l'on puisse trouver, mais j'avais déjà implémenté celui-ci. Je ne me suis donc pas cassé la tête.

Merci pour vos critiques, je vais voir ce que je peux faire.
eomer212 Messages postés 13 Date d'inscription lundi 7 février 2011 Statut Membre Dernière intervention 8 février 2011
24 sept. 2010 à 12:05
si j'ai bien compris, tu veux compter les occurences de caractéres de 0 à 255 stockés sous forme d'un octet dans un fichier.
alors, c'est l'une des plus mauvaises facons de procéder.
plusieurs raisons:
pour la premiere, je rejoint vincenzo, reallouer dynamiquement le caractere lu est une immense perte de temps, d'espace, et un risque potentiel accru inutilement.
une variable allouée aurait largement suffie.
ensuite, une chose qui m'a fait sauter de ma chaise, c'est que tu parcours 256 fois le fichier.. pour tester à chaque fois la presence du même caractére.
anodin dans le cas d'un petit fichier, mais essaie la meme chose avec par exemple un .avi ou divx de 700 MO.. la tu vas criser, c'est pas possible, trop long.
la 'bonne' solution, ou du moins celle qui est beaucoup plus optimisée et efficace pour ce cas, c'est de creer une table de stockage d'entiers avec un index, de lire chaque caractére du fichier à partir d'un buffer alloué une fois et recharger avec la portion de fichier à parcourir, et d'incrementer le contenu d'une table d'index (numero du caractere),
a la fin, tu comptes le total, et tu fais tes ratios..
donc en clair, pseudo code:

largeur=sizeof(unsigned long int); // pour jouer avec les pointeurs, toujours vérifier la largeur de stockage d'une variable, sinon surprises potentielles..
unsigned long in *presents; // table de stockage du comptage
presents=malloc(largeur*256); // allocation de la table de stockage je le fais en pointeur, mais ca aurait pu tout aussi bien etre une variable unsigned long int presents[256]
unsigned char caractere; // pour detailler, et stocker temporairement le caractere lu du buffer de lecture fichier
while (readfiletobuffer)
{
suivant=0;
for (i=0;i<longueur lue dans le buffer;i++)
{
caractere=*(buffer+i); // recuperer le caractere à partir du buffer de lecture
*(presents+i)++; // incrementer la table à la position ascii correspondante
}
}
la table presents contient pour chaque index de 0 à 255, le nombre d'itérations du caractére rencontré..
simple, rapide, efficace..
aprés, la, tu peux t'amuser et faire du tri à bulle, en passant complétement dépassé, mais suffisant pour trier 255 valeurs.
il serait bien, de sortir la table triée avec en premier le numero ascii reel justifié, et ensuite le caractére..

pour aller loin et vite, penser faineant..
cs_vicenzo Messages postés 178 Date d'inscription mardi 16 août 2005 Statut Membre Dernière intervention 25 août 2010 1
24 sept. 2010 à 09:52
la seule chose que je dis c'est :
- un realloc par caractère lu d'un fichier ne sert à rien. Un seul malloc avec la taille du fichier suffit
- utiliser un buffer alloué dynamiquement ne sert à rien. La lecture directe du fichier avec mis à jour de la table des occurrences suffit.
Donc, pourquoi se compliquer la vie en utilisant un buffer, qui plus est, réalloué X fois inutilement ?
sholvaC Messages postés 12 Date d'inscription mercredi 29 avril 2009 Statut Membre Dernière intervention 30 avril 2009
24 sept. 2010 à 09:44
Je vais modifier donc ce point et maj la source. Merci pour vos commentaires.
sholvaC Messages postés 12 Date d'inscription mercredi 29 avril 2009 Statut Membre Dernière intervention 30 avril 2009
24 sept. 2010 à 09:43
Ok, on est d'accord que c'est lent mais ne dites pas que c'est faux s'il vous plait. Ce n'est pas la même chose.
cs_vicenzo Messages postés 178 Date d'inscription mardi 16 août 2005 Statut Membre Dernière intervention 25 août 2010 1
24 sept. 2010 à 09:27
primo, la taille exacte du fichier peut être obtenue par un ftell des l'ouverture du fichier, ce qu permet de ne faire qu'un seul malloc au total. Dans ton code, si ton fichier fait 1Mo, tu fais 1 million de realloc. Ca sert a rien et il n'y a rien de plus inefficace...
Enfin, tu n'a pas besoin d'allouer un buffer pour stocker le contenu du fichier.
sholvaC Messages postés 12 Date d'inscription mercredi 29 avril 2009 Statut Membre Dernière intervention 30 avril 2009
24 sept. 2010 à 08:54
Si je fais ça c'est pour allouer justement pile poil ce qu'il faut ! Je ne comprends pas en quoi c'est une perte de mémoire ?! Une perte de temps oui car on pourrait compter le nombre de caractères présents puis allouer. Certes ce serait plus rapide mais j'avais envi de mettre en œuvre la fonction realloc. Mais je ne vois pas en quoi cela n'est pas correct de procéder ainsi !
cs_vicenzo Messages postés 178 Date d'inscription mardi 16 août 2005 Statut Membre Dernière intervention 25 août 2010 1
24 sept. 2010 à 08:26
salut,

tu lis ton fichier caractère par caractère et à fois chaque tu réalloues ton buffer !!

Grosses perte de temps et de mémoire inutile !

Faut revoir tout ca...
Rejoignez-nous