Novembre 2024 | Lun | Mar | Mer | Jeu | Ven | Sam | Dim |
---|
| | | | 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 | | Calendrier |
|
|
| Tri de chaînes de caractères | |
| | Auteur | Message |
---|
JL35
Nombre de messages : 7112 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Tri de chaînes de caractères Mer 21 Mar 2012 - 22:09 | |
| Je mets ça ici pour ne pas polluer les posts de bignono et cosmos, où l'on parlait de tri de chaînes. En général le SORT convient pour trier des chaînes, sauf que le tri se fait de manière 'intelligente', sans suivre strictement la valeur Ascii des caractères. Ainsi les majuscules et minuscules sont indifférenciées, par exemple "abc" sera classé avant "Bbc", ce qui est logique pour une liste de noms, mais pas forcément pour d'autres utilisations. Dans ces cas-là il faut se programmer sa propre méthode de tri. J'ai choisi la méthode la plus 'bestiale' et la plus lente, mais la plus facile à réaliser, le tri par bulle (bubble sort). Le principe est de comparer successivement tous les éléments du tableau en partant du bas avec ceux qui le suivent, et de permuter si un élément suivant est plus petit. Ici les données à trier sont dans des datas (exemple donné par cosmos), mais on peut tout aussi bien trier un fichier ascii, comme suggéré en commentaire. De même j'ai mis deux LIST parallèles, pour afficher la liste non triée puis triée, pour l'exemple, mais le tri se fait dans un seul LIST (ou dans un tableau), par permutations successives. Le 'display' (mis en commentaire) n'est là que pour la vue, pour faire patienter si la liste à trier est longue. En effet la méthode n'est pas optimisée, et on doit pouvoir faire mieux: - Code:
-
' Tribul.bas tri par bulle (selon l'ordre ascii des caractères) LABEL Tribul DIM a$(1000), b$, na%, rg%, i, t1, t2 HEIGHT 0, 1100 LIST 1: WIDTH 1, 300: HEIGHT 1, 1000: TOP 1,25 LIST 2: WIDTH 2, 300: HEIGHT 2, 1000: LEFT 2,310: TOP 2,25 FONT_NAME 1,"Lucida Console": FONT_SIZE 1,10: FONT_NAME 2,"Lucida Console": FONT_SIZE 2,10 DATA "MemoChoixStyle","MemoValideEdit","Memo_applique_Style","MemoStyleEdit","MemoClicEditStyle" DATA "Memo_Cde_Style","MemoListeStyle","Memo_Zoom","Memo_Scroll_color","Memo_Show","Memo_Hide" DATA "Memo_Size","Memo_Fonte","Memo_Color","Memo_Alpha","Memo_Fond","Memo_Attribut","Memo_Copie","Memo_Fichier" DATA "MemoCalcul","MemoData","MemoChange","Memo_Lecture_Style","quite_Memo_Include","LIRE_MemoRich" DATA "$$$" READ b$: na% = 0 WHILE b$ <> "$$$" na% = na% + 1: a$(na%) = b$ READ b$ END_WHILE rg% = 1: ' rang de début de tri dans l'article
' file_open_read 1,"C:\Textes\pgville.txt": na% = 0: ' 250 villes les plus peuplées ' while file_eof(1) = 0: na%=na%+1: file_readln 1,a$(na%): end_while ' file_close 1 ' rg% = 5
FOR i = 1 TO na%: ITEM_ADD 1, a$(i): NEXT i: display t1 = VAL(RIGHT$(TIME$,2))+60*VAL(MID$(TIME$,4,2))+3600*VAL(LEFT$(TIME$,2)) GOSUB Tribul t2 = VAL(RIGHT$(TIME$,2))+60*VAL(MID$(TIME$,4,2))+3600*VAL(LEFT$(TIME$,2)) FOR i = 1 TO na%: ITEM_ADD 2, a$(i): NEXT i: ' affichage du tableau trié PRINT "Terminé, durée= " + STR$(t2-t1) + " s." END
Tribul: ' Tri croissant du tableau a$() de na% articles, ' à partir du caractère de rang rg% DIM iv$, jv$, bt$, vi, vj, it, jt, kt FOR it = 1 TO na%-1 iv$ = MID$(a$(it), rg%, 1000) FOR jt = it+1 TO na% jv$ = MID$(a$(jt), rg%, 1000) IF LEN(jv$) > LEN(iv$) iv$ = iv$ + STRING$(LEN(jv$)-LEN(iv$)," ") ELSE IF LEN(iv$) > LEN(jv$) jv$ = jv$ + STRING$(LEN(iv$)-LEN(jv$)," ") END_IF END_IF FOR kt = 1 TO LEN(iv$) vi = ASC(MID$(iv$,kt,1)) vj = ASC(MID$(jv$,kt,1)) IF vj < vi: ' plus petit, on permute bt$ = a$(it): a$(it) = a$(jt): a$(jt) = bt$: ' swap iv$ = MID$(a$(it), rg%, 1000) EXIT_FOR END_IF IF vj > vi THEN EXIT_FOR: ' plus grand, on sort NEXT kt NEXT jt ' display NEXT it FREE iv$: FREE jv$: FREE bt$: FREE vi: FREE vj: FREE it: FREE jt: FREE kt RETURN
Dernière édition par JL35 le Jeu 22 Mar 2012 - 17:13, édité 3 fois | |
| | | Jean Claude
Nombre de messages : 5950 Age : 70 Localisation : 83 Var Date d'inscription : 07/05/2009
| Sujet: Re: Tri de chaînes de caractères Jeu 22 Mar 2012 - 11:23 | |
| Salut JL35, C'est somme toute assez rapide et l'on choisi son type de tri. Je me le met dans mes exemples... Pour bien montrer la différence avec SORT j'ai ajouter un 3éme LIST et un bouton pour déclencher le tri des mêmes mots avec SORT. - Code:
-
' Tribul.bas tri par bulle (selon l'ordre ascii des caractères) dim iv$, jv$, vi, vj, i, j, k, per label sort3 height 0, 800:width 0,630 list 1: width 1, 200: height 1, 700: top 1,25 list 2: width 2, 200: height 2, 700: left 2,210: top 2,25 list 3: width 3, 200: height 3, 700: left 3,420: top 3,25 button 4:top 4,730:left 4,450:width 4,150:caption 4,"Tri de LIST 3 avec SORT":on_click 4,sort3 font_name 1,"Lucida Console": font_size 1,10: font_name 2,"Lucida Console": font_size 2,10 data "MemoChoixStyle","MemoValideEdit","Memo_applique_Style","MemoStyleEdit","MemoClicEditStyle" data "Memo_Cde_Style","MemoListeStyle","Memo_Zoom","Memo_Scroll_color","Memo_Show","Memo_Hide" data "Memo_Size","Memo_Fonte","Memo_Color","Memo_Alpha","Memo_Fond","Memo_Attribut","Memo_Copie","Memo_Fichier" data "MemoCalcul","MemoData","MemoChange","Memo_Lecture_Style","quite_Memo_Include","LIRE_MemoRich" data "$$$" read iv$ while iv$ <> "$$$" item_add 1, iv$: item_add 2, iv$ item_add 3,iv$:' pour le tri avec SORT read iv$ end_while ' file_load 1, "c:\textes\lorem.txt": ' pour trier un fichier ascii ' file_load 2, "c:\textes\lorem.txt" for i = 1 to count(2)-1 iv$ = item_read$(2,i) for j = i+1 to count(2) jv$ = item_read$(2,j) if len(jv$) > len(iv$) iv$ = iv$ + string$(len(jv$)-len(iv$)," ") else if len(iv$) > len(jv$) jv$ = jv$ + string$(len(iv$)-len(jv$)," ") end_if end_if per = 0 for k = 1 to len(iv$) vi = asc(mid$(iv$,k,1)) vj = asc(mid$(jv$,k,1)) if vj < vi then per = 1: exit_for: ' plus petit, on permute if vj > vi then exit_for: ' plus grand, on sort next k if per = 1 ' permutation item_delete 2,i: item_insert 2,i,rtrim$(jv$) item_delete 2,j: item_insert 2,j,rtrim$(iv$) iv$ = rtrim$(jv$) end_if next j ' display next i print "Terminé !" end sort3: sort 3 return
A+ | |
| | | JL35
Nombre de messages : 7112 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Tri de chaînes de caractères Jeu 22 Mar 2012 - 13:23 | |
| Bonjour Jean Claude, tu as oublié le gosub sort3 juste avant le print "Terminé", sinon on ne voit rien ! La méthode bulle est assez rapide pour de petites listes, je pense que la durée d'exécution est exponentielle en fonction de la taille de la liste. Comme je disais la méthode Sort se justifie pour des tris de listes de noms etc. Par contre, dans une utilisation technique comme celle de cosmos: liste de labels, variables, etc, il me semble que le tri purement ascii se justifie plus. PS j'ai édité ci-dessus : le tri se fait dans un sous-programme indépendant, plus transportable. Tri du tableau a$() de na% éléments. J'ai ajouté également une mesure du temps d'exécution, en secondes (on ne dispose pas de mesure du temps plus fine, hélas), ce qui permet de faire des essais sur des listes plus longues, pour voir l'incidence sur la durée d'exécution. (et aussi pour voir l'incidence d'optimisations éventuelles). | |
| | | Jean Claude
Nombre de messages : 5950 Age : 70 Localisation : 83 Var Date d'inscription : 07/05/2009
| Sujet: Re: Tri de chaînes de caractères Jeu 22 Mar 2012 - 14:24 | |
| RE_Salut JL35, Je n'ai pas oublié le GOSUB, il y a un bouton (pourtant il est gros ) en bas du list n°3 Je croyais l'avoir dit: - Citation :
- Pour bien montrer la différence avec SORT j'ai ajouter un 3éme LIST et un bouton pour déclencher le tri des mêmes mots avec SORT.
Pour la peine tu me copieras 100 fois "Je dois bien lire les messages, surtout ceux de Jean Claude". A+ | |
| | | JL35
Nombre de messages : 7112 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Tri de chaînes de caractères Jeu 22 Mar 2012 - 14:34 | |
| Oups ! je n'avais pas vu le bouton (pas si gros que ça, chez moi il est à moitié masqué par les barres de défilement... bon, c'est une excuse de mauvaise foi, et j'ai lu ton message en diagonale). Bon, j'ai copié mes 100 fois, je te les envoie en port dû et contre remboursement pour le papier.
PS j'ai ajouté la possibilité de trier à partir d'un rang donné dans l'article (pour des listes qui comportent plusieurs données par article). Mais après essais sur des listes plus longues, il faut bien reconnaître que ça devient vite rédhibitoire. Sauf si on n'a à le faire qu'une seule fois en passant, et aller boire un coup pendant le travail. | |
| | | papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
| Sujet: Re: Tri de chaînes de caractères Jeu 22 Mar 2012 - 22:00 | |
| Salut à tous ! Question de tri, je vous propose ma modeste contribution : le tri de Shell-Metzner. La méthode de Shell-Metzner est très efficace, surtout dans le cas où la liste est déjà partiellement ordonnée. La méthode est dérivée du tri par interclassements, qui considère une liste de n éléments comme n listes de un élément, puis les classe 2 à 2. Le processus est alors réitéré avec des listes à 2 éléments puis 4, etc. A chaque étape les éléments sont comparés et permutés si besoin est. Le tri de Shell-Metzner s’appuie sur ce principe en appariant les éléments 2 à 2,de manière enchevêtrée, et en faisant des retours en arrière chaque fois qu’une permutation est effectuée pour améliorer le rangement de la sous-liste considérée. Le programme ci-dessous est une démonstration de son emploi. Chacun peut l'adapter à ses besoins. NB : Le tri à bulle est le plus simple et le plus compact des algorithmes. Les mauvaises performances de ce type de tri proviennent du fait que, dans tous les cas on est sûr d’avoir un nombre de comparaison équivalent au carré du nombre de données à trier, même sur une liste déjà triée. - Code:
-
' Tri rapide de Shell-Metzner ' par Papydall
dim n,i,j,ecart,permut,false,true ,temp n = 50 : dim table(n) false = 0 : true = 1 : n = 50 label permuter,ChargerTable,Tri_Shell_Metzner height 0, 800 list 1: width 1, 200: height 1, 700: top 1,25 list 2: width 2, 200: height 2, 700: left 2,210: top 2,25
gosub ChargerTable gosub Tri_Shell_Metzner end
' Charger une table d'entiers aléatoires pour la trier ChargerTable: item_add 1,"Liste non triée" item_add 1," " for i = 1 to n table(i) = int(rnd(2000)) ' Afficher la liste non triée
item_add 1,table(i) next i return
' Algorithme de tri à adapter à ce qu'on veut trier Tri_Shell_Metzner: ecart = int(n/2) while ecart <> 0 for i = 1 to n - ecart j = i : permut = true while j > 0 and permut = true permut = false if table(j) > table(j + ecart) gosub permuter permut = true j = j - ecart end_if end_while next i ecart = int(ecart/2) end_while ' Afficher la table triée item_add 2,"Liste triée" item_add 2," " for i = 1 to n item_add 2, table(i) next i return
' Pour permuter 2 valeurs permuter: temp = table(j) table(j) = table(j+ecart) : table(j+ecart) = temp return
| |
| | | JL35
Nombre de messages : 7112 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Tri de chaînes de caractères Jeu 22 Mar 2012 - 22:53 | |
| Je savais bien qu'il existait d'autres méthodes de tri beaucoup plus performantes (shell, quick etc) que le tri à bulles, je voulais faire au plus simple, mais je vais regarder ton exemple de shell metzner avec grand intérêt !
En tout cas merci papydall pour les explications mathématiques.
PS Tout de même, après un rapide coup d'oeil, je m'aperçois que tu donnes un exemple de tri de valeurs numériques si je ne me trompe. Pour ça il n'y a pas de problème en Panoramic, puisque le SORT fait très bien l'affaire (il utilise certainement un algorithme de tri plus sophistiqué que le tri bulles).
Le problème que je tentais de résoudre ici était le tri de chaînes de caractères en fonction de leur stricte valeur Ascii, c'est à dire dans l'ordre 0...1, A...Z, a...z etc. Et ça c'est une autre paire de manches pour le coder en Panoramic pur autrement qu'en tri à bulles, puisqu'on ne dispose pas d'instruction pour comparer deux chaînes ! Alors si tu as une idée plus précise...
Dernière édition par JL35 le Jeu 22 Mar 2012 - 23:03, édité 1 fois | |
| | | papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
| Sujet: Re: Tri de chaînes de caractères Jeu 22 Mar 2012 - 23:02 | |
| Salut JL35 ! Je suis très content de partager le peu de chose que je connais. A + | |
| | | JL35
Nombre de messages : 7112 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Tri de chaînes de caractères Jeu 22 Mar 2012 - 23:04 | |
| On s'est croisés... Néanmoins je vais essayer d'adapter ma comparaison de chaînes à ton algorithme, ça devrait le faire, mais ralentir quand même le processus. | |
| | | JL35
Nombre de messages : 7112 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Tri de chaînes de caractères Ven 23 Mar 2012 - 17:10 | |
| Voilà papydall, j'ai intégré ta méthode au tri de chaînes et ça marche parfaitement: par exemple je trie le fichier des 255 communes de France les plus peuplées, classées dans le fichier par ordre d'importance, à partir du 5ème caractère de chaque article pour trier les villes par ordre alphabétique. Résultat: Tri par bulles: durée 18 secondes Tri shell: durée 2 à 3 secondes, donc le gain est considérable. J'ai laissé dans le programme les deux sous-programmes: bulles et shell, pour pouvoir faire des comparaisons: - Code:
-
' Tri.bas tri selon l'ordre ascii des caractères LABEL Tribul, Trishell DIM a$(1000), b$, na%, rg%, i, t1, t2 HEIGHT 0, 1100 LIST 1: WIDTH 1, 300: HEIGHT 1, 1000: TOP 1,25 LIST 2: WIDTH 2, 300: HEIGHT 2, 1000: LEFT 2,310: TOP 2,25 FONT_NAME 1,"Lucida Console": FONT_SIZE 1,10: FONT_NAME 2,"Lucida Console": FONT_SIZE 2,10 DATA "MemoChoixStyle","MemoValideEdit","Memo_applique_Style","MemoStyleEdit","MemoClicEditStyle" DATA "Memo_Cde_Style","MemoListeStyle","Memo_Zoom","Memo_Scroll_color","Memo_Show","Memo_Hide" DATA "Memo_Size","Memo_Fonte","Memo_Color","Memo_Alpha","Memo_Fond","Memo_Attribut","Memo_Copie","Memo_Fichier" DATA "MemoCalcul","MemoData","MemoChange","Memo_Lecture_Style","quite_Memo_Include","LIRE_MemoRich" DATA "$$$" READ b$: na% = 0 WHILE b$ <> "$$$" na% = na% + 1: a$(na%) = b$ READ b$ END_WHILE rg% = 1: ' rang de début de tri dans l'article ' ============================================================================== ' ci-dessous, tri alphabétique du fichier des 255 communes les plus peuplées de ' france, à partir du 5ème caractère (le début d'article étant le rang 0 à 255) ' file_open_read 1,"C:\Textes\pgville.txt": na% = 0: ' 255 villes les plus peuplées ' while file_eof(1) = 0: na%=na%+1: file_readln 1,a$(na%): end_while ' file_close 1 ' rg% = 5 ' ============================================================================== FOR i = 1 TO na%: ITEM_ADD 1, a$(i): NEXT i: display t1 = VAL(RIGHT$(TIME$,2))+60*VAL(MID$(TIME$,4,2))+3600*VAL(LEFT$(TIME$,2)) ' GOSUB Tribul GOSUB Trishell t2 = VAL(RIGHT$(TIME$,2))+60*VAL(MID$(TIME$,4,2))+3600*VAL(LEFT$(TIME$,2)) FOR i = 1 TO na%: ITEM_ADD 2, a$(i): NEXT i: ' affichage du tableau trié PRINT "Terminé, durée= " + STR$(t2-t1) + " s." END
Tribul: ' Tri croissant du tableau a$() de na% articles, ' à partir du caractère de rang rg% (méthode bubble sort) DIM iv$, jv$, bt$, vi, vj, it, jt, kt FOR it = 1 TO na%-1 iv$ = MID$(a$(it), rg%, 1000) FOR jt = it+1 TO na% jv$ = MID$(a$(jt), rg%, 1000) IF LEN(jv$) > LEN(iv$) iv$ = iv$ + STRING$(LEN(jv$)-LEN(iv$)," ") ELSE IF LEN(iv$) > LEN(jv$) jv$ = jv$ + STRING$(LEN(iv$)-LEN(jv$)," ") END_IF END_IF FOR kt = 1 TO LEN(iv$) vi = ASC(MID$(iv$,kt,1)) vj = ASC(MID$(jv$,kt,1)) IF vj < vi: ' plus petit, on permute bt$ = a$(it): a$(it) = a$(jt): a$(jt) = bt$: ' swap iv$ = MID$(a$(it), rg%, 1000) EXIT_FOR END_IF IF vj > vi THEN EXIT_FOR: ' plus grand, on sort NEXT kt NEXT jt ' display NEXT it FREE iv$: FREE jv$: FREE bt$: FREE vi: FREE vj: FREE it: FREE jt: FREE kt RETURN
Trishell: ' Tri croissant du tableau a$() de na% articles, ' à partir du caractère de rang rg% ' (méthode shell-metzner sort, dite aussi papydall sort) DIM a1$, b1$, ecart, is, js, permut, temp$, va, vb, rc%, ktc ecart = INT(na%/2) WHILE ecart <> 0 FOR is = 1 TO na% - ecart js = is : permut = 1 WHILE js > 0 AND permut = 1 permut = 0 a1$ = MID$(a$(js), rg%, 1000) b1$ = MID$(a$(js+ecart), rg%, 1000) IF LEN(a1$) > LEN(b1$) b1$= b1$ + STRING$(LEN(a1$)-LEN(b1$)," ") ELSE IF LEN(b1$) > LEN(a1$) a1$ = a1$ + STRING$(LEN(b1$)-LEN(a1$)," ") END_IF END_IF rc% = 0 FOR ktc = 1 TO LEN(a1$) va = ASC(MID$(a1$, ktc, 1)) vb = ASC(MID$(b1$, ktc, 1)) IF vb < va THEN rc% = 1: EXIT_FOR IF vb > va THEN rc% = -1: EXIT_FOR NEXT ktc IF rc%= 1 temp$ = a$(js) a$(js) = a$(js+ecart) : a$(js+ecart) = temp$ permut = 1 js = js - ecart END_IF END_WHILE NEXT is ecart = INT(ecart/2) END_WHILE FREE a1$: FREE b1$: FREE ecart: FREE is: FREE js: FREE temp$ FREE va: FREE vb: FREE rc%: FREE ktc RETURN
Evidemment, dans le tri de noms de villes la commande SORT conviendrait mieux, sinon comme ici avec l'ordre ascii on se retrouve avec Watrelos avant Évry... | |
| | | papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
| Sujet: Re: Tri de chaînes de caractères Ven 23 Mar 2012 - 18:11 | |
| Salut JL35 ! Ton adaptation du tri Shell-Metzner est parfaite. Mais tu me fais un honneur que je ne mérite pas. L’algorithme est dit de Shell-Metzner. Moi, je n’ai fait que le coder. Et je suis content qu’il ait servi à quelque chose. A+
| |
| | | JL35
Nombre de messages : 7112 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Tri de chaînes de caractères Ven 23 Mar 2012 - 18:26 | |
| Merci à toi en tout cas d'en avoir donné la substance.
Je mets quand même un bémol à cette histoire de tri de chaînes, ça va bien pour une centaine d'articles, mais pour de longs fichiers c'est trop long, quelle que soit la méthode. Ce qui plombe le tout c'est cette comparaison de deux chaînes, caractère par caractère, ça c'est bien trop long à l'exécution dès que les chaînes à comparer sont un peu longues. | |
| | | Jean Claude
Nombre de messages : 5950 Age : 70 Localisation : 83 Var Date d'inscription : 07/05/2009
| Sujet: Re: Tri de chaînes de caractères Ven 23 Mar 2012 - 21:12 | |
| Salut à vous deux,
j'ai testé en activant tour à tour les lignes 29 et 30, franchement dans les 2 cas j'ai un tri du même timing. C'est, je suppose, la taille du fichier à trier....
En tout cas, très intéressant...
A+. | |
| | | JL35
Nombre de messages : 7112 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Tri de chaînes de caractères Ven 23 Mar 2012 - 22:11 | |
| Bonsoir Jean Claude, merci d'avoir essayé. Tu as le même timing parce que tu tries une petite liste, ce n'est pas significatif. Essaie de trier un fichier texte de 100 ou 200 lignes lignes, tu verras la différence.
J'ai une autre méthode bien plus efficace, avec un script vbs intégré dans le code Panoramic, que j'ai adapté pour pouvoir trier à partir d'un rang de caractère donné. Si ça t'intéresse je le donnerai ici (je l'ai déjà donné ailleurs sous une autre forme, il me semble). En tout cas c'est infiniment plus rapide. | |
| | | papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
| Sujet: Re: Tri de chaînes de caractères Ven 23 Mar 2012 - 22:57 | |
| Salut à tous ! Faute de disposer en PANORAMIC de la fonction de comparaison de 2 chaines de caractères (quelque chose comme : IF C1$ > C2$ then ….), voici un sous-programme de comparaison de 2 chaînes de caractères C1$ et C2$ selon l’ordre ASCII. Le résultat de la comparaison est le suivant : -1 si C1$ est inferieure à C2$ 0 si les 2 chaînes sont identiques +1 si C1$ est supérieure à C2$ A essayer ! - Code:
-
' Comparaison de deux chaînes de caractères C1$ et C2$ ' selon l'ordre ASCII des caractères ' ' Le resultat est : -1 si C1$ < C2$ ' 0 si C1$ = C2$ ' +1 si C1$ > C2$
dim c1$,c2$,result,L1,L2,L,i label ComparerChaine ' Exemples pour le test c1$ = "Aabc" : c2$ = "a" : gosub ComparerChaine c1$ = "aBCabcd" : c2$ = "ABCabcdxxx" : gosub ComparerChaine c1$ = "123" : c2$ = "123456" : gosub ComparerChaine c1$ = "éèà" : c2$ = "eeaazer" : gosub ComparerChaine c1$ = "azerty" : c2$ = "azerty" : gosub ComparerChaine c1$ = "azerty" : c2$ = "Azerty" : gosub ComparerChaine end
ComparerChaine:
L1 = len(c1$) : L2 = len(c2$) : L = min(L1,L2) i = 1 : result = 0 while i <= L if asc(mid$(c1$,i,1)) > asc(mid$(c2$,i,1)) result = 1 : exit_while : ' La chaîne c1$ est plus grande que c2$ : on sort de la boucle end_if if asc(mid$(c1$,i,1)) < asc(mid$(c2$,i,1)) result = -1 : exit_while :' La chaîne c1$ est plus petite que c2$ : on sort de la boucle end_if i = i + 1 end_while if result = 0 :' Pour traiter le cas où les 2 chaînes ont les mêmes premiers caractères if L1 <> L2 if L1 = L result = -1 else result = 1 end_if end_if end_if select result case -1 : print c1$ ; " < " ; c2$ case 0 : print c1$ ; " = " ; c2$ case +1 : print c1$ ; " > " ; c2$ end_select return
Le tri Shell-Metzner est très rapide par rapport au tri à bulle (la différence est significative pour des grandes valeurs à trier). | |
| | | JL35
Nombre de messages : 7112 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Tri de chaînes de caractères Ven 23 Mar 2012 - 23:06 | |
| C'est un peu ce que j'ai fait dans mon programme ci-dessus, mais c'est ça qui prend un temps fou, la comparaison des chaînes caractère par caractère, par rapport au tri lui-même.
La méthode du script vbs est infiniment plus rapide. | |
| | | papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
| Sujet: Re: Tri de chaînes de caractères Ven 23 Mar 2012 - 23:20 | |
| Espérons que cette fonction sera intégrée dans une future version ! | |
| | | exdragon
Nombre de messages : 601 Date d'inscription : 05/01/2012
| Sujet: Re: Tri de chaînes de caractères Dim 25 Mar 2012 - 8:52 | |
| Je rajoute mon bravo aussi à papydall pour avoir proposé le shell metzer - Citation :
- Pour la peine tu me copieras 100 fois "Je dois bien lire les messages,
Pour une fois que ce n'est pas moi qui te le dit jl35^^ Moi je ne te faisais pas travailler tes lignes, c'est vrai^^ J'aurais dû JL35, tu me donne une idée grace à ta remarque sur la lourdeur de comparaison quand la liste des chaines est longue, on pourrait peut-être faire un tri non pas sur toute la longueur de la chaine mais seulement sur les 5 premiers caractères de chaque chaine, et quand c'est trié, refaire le test pour les chaines restantes à égalité, en faisant les 5 caractères suivants. | |
| | | JL35
Nombre de messages : 7112 Localisation : 77 Date d'inscription : 29/11/2007
| Sujet: Re: Tri de chaînes de caractères Dim 25 Mar 2012 - 14:04 | |
| C'est une idée, mais ça ne me paraît pas du tout évident à coder, ça semble vouloir dire qu'il faudra refaire le tri tous les 5 caractères, avec tous ces tests successifs ça risque d'être encore plus lourd. Mais si tu veux te lancer, tu as ma bénédiction ! Mon idée c'est que 1) ce serait bien que ce soit intégré dans Panoramic, le test if a$ > b$ basé sur la valeur ascii. 2) et à défaut, j'ai le script vbs (qui intègre cette comparaison) qui fait bien l'affaire, sans faire appel à une ressource externe. Tiens, le tri de chaînes avec script vbs intégré (on peut trier à partir d'un rang donné dans la chaîne, ici 5, et comme toujours les noms de fichiers sont à adapter suivant les conditions locales): - Code:
-
' Tri de chaînes suivant la valeur Ascii des caractères DIM f1$, f2$, rng%, t1, t2 DIM scr$, script$: scr$ = "Tri.vbs" LABEL Trivbs
DATA "Tri.vbs" DATA "Option Explicit" DATA "' Tri de chaînes dans l'ordre des valeurs Ascii" DATA "' Paramètres: fichieràtrier fichierrésultat [index de tri]" DATA "' (peuvent être identiques)" DATA "Dim objFso, objTextFile" DATA "Dim arrLines" DATA "Dim bpermute, cprovisoire, i, j, Rang, args" DATA "Dim MyFile, MySortedFile" DATA "args = wscript.Arguments.Count" DATA "MyFile = wscript.Arguments(0)" DATA "MySortedFile = wscript.Arguments(1)" DATA "Rang = 1" DATA "If args > 2 Then Rang = wscript.Arguments(2)" DATA "" DATA "Set objFso = CreateObject("+CHR$(34)+"Scripting.FileSystemObject"+CHR$(34)+")" DATA "Set objTextFile = objFso.OpenTextFile(MyFile, 1)" DATA "arrLines = Split(objTextFile.ReadAll,vbCrLf)" DATA "objTextFile.Close " DATA "" DATA "bpermute = True" DATA "Do While bpermute = True" DATA " bpermute = False" DATA " For i = UBound(arrLines) To 1 Step -1" DATA " If Len(arrLines(i)) > 1 Then" DATA " For j = 0 To i - 1" DATA " If Len(arrLines(j)) > 1 Then" DATA " If Mid(Split(arrLines(j), Chr(44))(0), Rang) >_" DATA " Mid(Split(arrLines(j + 1), Chr(44))(0), Rang) Then" DATA " cprovisoire = arrLines(j)" DATA " arrLines(j) = arrLines(j + 1)" DATA " arrLines(j + 1) = cprovisoire" DATA " bpermute = True" DATA " End If" DATA " End If" DATA " Next" DATA " End If" DATA " Next" DATA "Loop" DATA "'Write File" DATA "Set objTextFile = objFso.CreateTextFile(MySortedFile, 2)" DATA "For i = 0 To UBound(arrLines)" DATA " objTextFile.WriteLine arrLines(i)" DATA "Next" DATA "objTextFile.Close" DATA "Set objTextFile = Nothing" DATA "Set objFso = Nothing" DATA "f" READ script$ WHILE script$ <> scr$: READ script$: END_WHILE: ' rephasage sur les datas FILE_OPEN_WRITE 9, "C:\Temp" + scr$ READ script$ WHILE script$ <> "f": FILE_WRITELN 9, script$: READ script$: END_WHILE FILE_CLOSE 9 script$ = "C:\Temp" + scr$: ' script à exécuter
HEIGHT 0, 900: WIDTH 0, 840 LIST 1: HEIGHT 1, 800: WIDTH 1, 400 LIST 2: HEIGHT 2, 800: LEFT 2, 410: WIDTH 2, 400 ' =================================================== A VOIR ! ================ f1$ = "C:\Temp\Test.txt": ' ***** Fichier à trier rng% = 5: ' index de début de tri par chaîne f2$ = "C:\Temp\FTrie.txt": ' ***** Fichier résultat ' ============================================================================= FILE_LOAD 1, f1$ t1 = VAL(RIGHT$(TIME$,2))+60*VAL(MID$(TIME$,4,2))+3600*VAL(LEFT$(TIME$,2)) GOSUB Trivbs: ' tri par la méthode script vbs t2 = VAL(RIGHT$(TIME$,2))+60*VAL(MID$(TIME$,4,2))+3600*VAL(LEFT$(TIME$,2)) FILE_LOAD 2, f2$ MESSAGE "Durée= " + STR$(t2-t1) + " s." END
Trivbs: ' arguments: fichier à trier, fichier résultat, index début de tri (optionnel, =1 implicite) EXECUTE_WAIT "Wscript.exe " + script$ + " " + f1$ + " " + f2$ + " " + STR$(rng%) RETURN
| |
| | | Contenu sponsorisé
| Sujet: Re: Tri de chaînes de caractères | |
| |
| | | | Tri de chaînes de caractères | |
|
Sujets similaires | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |