Liste a re-ordonner !

Le
loiseauthierry
Bonjour, petit devoir de vacacances :)

Soit un fichier text contenant par exemple ceci :

txt
15: yep (2)
14: a b cdde (5)
13: dqgdqg (0)
12: dhhh h (12)
11: dd d (8)
10: - dfgs - (0)
9: [qdfdd]hsfhfh (5)
8: ddfsqdfsdfs (2)
6: dfq d (1000)
5: M() (5)
4: dfqd'/p d'dfd (2)
3: pabcqd qdfqd (2)
2: Pddcé gvpt (7)
1: A l'abcd (2)
/txt

Comment faire pour réordonner ceci, réenregistrer dans un autre fichier
texte de telle sorte que la première ligne représente le numéro le plus
grand qui se trouve entre parenthèses et en sous-ordre, le numéro se
trouvant en début de la ligne ?

Attention : ici il n'y a que 14 ligne (il manque le numéro 7)

Le programme doit être le plus court et le plus lisible possible :))

Merci et bon jeu !!

le résultat ici doit être ceci :

txt
6: dfq d (1000)
12: dhhh h (12)
11: dd d (8)
2: Pddcé gvpt (7)
14: a b cdde (5)
9: [qdfdd]hsfhfh (5)
5: M() (5)
15: yep (2)
8: ddfsqdfsdfs (2)
4: dfqd'/p d'dfd (2)
3: pabcqd qdfqd (2)
1: A l'abcd (2)
13: dqgdqg (0)
10: - dfgs - (0)
/txt
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Olivier Miakinen
Le #11186951
Le 04/07/2008 11:31, Thierry Loiseau a écrit :

[...]

Comment faire pour réordonner ceci, réenregistrer dans un autre fichier
texte de telle sorte que la première ligne représente le numéro le plus
grand qui se trouve entre parenthèses et en sous-ordre, le numéro se
trouvant en début de la ligne ?



J'y étais presque, avec un appel à la commande unix sort :
$ sort -t '(' -nr -k 2 -k 1 input.txt -o output.txt

La même chose en plus verbeux mais plus lisible :
$ sort --field-separator='(' --numeric-sort --reverse --key=2 --key=1
input.txt -o output.txt

Il aurait alors suffi de l'appeler par un system(), mais malheureusement
ça ne marche pas à cause des parenthèses de la ligne 5. Je vais donc le
faire directement en PHP.
Olivier Miakinen
Le #11187191
Le 04/07/2008 11:31, Thierry Loiseau a écrit :

Comment faire pour réordonner ceci, réenregistrer dans un autre fichier
texte de telle sorte que la première ligne représente le numéro le plus
grand qui se trouve entre parenthèses et en sous-ordre, le numéro se
trouvant en début de la ligne ?



function cmp($a, $b)
{
preg_match("/([0-9]+).[rn]*$/", $a, $ma);
preg_match("/([0-9]+).[rn]*$/", $b, $mb);
return $mb[1] - $ma[1]; // b - a car ordre inverse
}
$contenu = file($inputfile);
usort($contenu, 'cmp');
file_put_contents($outputfile, implode("n", $contenu)."n");


Note que tu pourrais utiliser l'option FILE_IGNORE_NEW_LINES pour la
fonction file() et du coup supprimer le [rn]* des regexp, mais il
paraît qu'il peut y avoir des problèmes si tu lis un fichier en format
DOS sur un Unix ou le contraire. Inversement, il faudra peut-être
adapter le "n" au moment de la réécriture.
Olivier Miakinen
Le #11187321
Le 04/07/2008 12:52, j'ai écrit n'importe quoi :

function cmp($a, $b)
{
preg_match("/([0-9]+).[rn]*$/", $a, $ma);
preg_match("/([0-9]+).[rn]*$/", $b, $mb);
return $mb[1] - $ma[1]; // b - a car ordre inverse
}
$contenu = file($inputfile);
usort($contenu, 'cmp');
file_put_contents($outputfile, implode("n", $contenu)."n");

[...] Inversement, il faudra peut-être
adapter le "n" au moment de la réécriture.



Mais non, justement ! Il vaut mieux garder les r ou n tels
qu'ils existent, et ne surtout pas en rajouter !


Donc :

function cmp($a, $b)
{
preg_match("/([0-9]+).[rn]*$/", $a, $ma);
preg_match("/([0-9]+).[rn]*$/", $b, $mb);
return $mb[1] - $ma[1]; // b - a car ordre inverse
}
$contenu = file($inputfile);
usort($contenu, 'cmp');
file_put_contents($outputfile, implode('', $contenu));


(Est-il besoin de préciser que je n'ai pas testé ?)
Pierre Maurette
Le #11188171
Olivier Miakinen, le 04/07/2008 a écrit :
Le 04/07/2008 11:31, Thierry Loiseau a écrit :

Comment faire pour réordonner ceci, réenregistrer dans un autre fichier
texte de telle sorte que la première ligne représente le numéro le plus
grand qui se trouve entre parenthèses et en sous-ordre, le numéro se
trouvant en début de la ligne ?



function cmp($a, $b)
{
preg_match("/([0-9]+).[rn]*$/", $a, $ma);
preg_match("/([0-9]+).[rn]*$/", $b, $mb);
return $mb[1] - $ma[1]; // b - a car ordre inverse
}
$contenu = file($inputfile);
usort($contenu, 'cmp');
file_put_contents($outputfile, implode("n", $contenu)."n");


Note que tu pourrais utiliser l'option FILE_IGNORE_NEW_LINES pour la
fonction file() et du coup supprimer le [rn]* des regexp, mais il
paraît qu'il peut y avoir des problèmes si tu lis un fichier en format
DOS sur un Unix ou le contraire. Inversement, il faudra peut-être
adapter le "n" au moment de la réécriture.



J'ai du mal à voir comment ça marche. Je vais faire tourner le truc,
puisque je me remets à faire un peu de PHP, donc que je traîne dans le
coin.

En python, pas particulièrement compact, on doit pouvoir faire proche
en PHP:

tri1 = lambda x, y: cmp(int(y.split('(')[-1].rstrip()[:-1]),
int(x.split('(')[-1].rstrip()[:-1]))
tri2 = lambda x, y: cmp(int(y.split(':')[0]), int(x.split(':')[0]))
tri = lambda x, y: tri1(x, y) or tri2(x, y)

s = open('in.txt', 'r').readlines().sort(cmp=tri)
open('out.txt', 'w').write(''.join(s))

--
Pierre Maurette
Bruno Desthuilliers
Le #11188331
Pierre Maurette a écrit :
(snip)
En python, pas particulièrement compact, on doit pouvoir faire proche en
PHP:



(snip code Python)

Ah woua l'autre, hé, et moi que j'ai répondu en premier avec une
splendide solution Python mon post il est pas passé ???

<meta>
Allo les modérateurs ? Ma soluce s'est perdue dans l'ether(pas net), ou
bien c'est du favoritisme éhonté ?
</meta>

(non, pas taper...)
Pierre Maurette
Le #11188851
(supersedes
Olivier Miakinen, le 04/07/2008 a écrit :
Le 04/07/2008 11:31, Thierry Loiseau a écrit :

Comment faire pour réordonner ceci, réenregistrer dans un autre fichier
texte de telle sorte que la première ligne représente le numéro le plus
grand qui se trouve entre parenthèses et en sous-ordre, le numéro se
trouvant en début de la ligne ?



function cmp($a, $b)
{
preg_match("/([0-9]+).[rn]*$/", $a, $ma);
preg_match("/([0-9]+).[rn]*$/", $b, $mb);
return $mb[1] - $ma[1]; // b - a car ordre inverse
}
$contenu = file($inputfile);
usort($contenu, 'cmp');
file_put_contents($outputfile, implode("n", $contenu)."n");


Note que tu pourrais utiliser l'option FILE_IGNORE_NEW_LINES pour la
fonction file() et du coup supprimer le [rn]* des regexp, mais il
paraît qu'il peut y avoir des problèmes si tu lis un fichier en format
DOS sur un Unix ou le contraire. Inversement, il faudra peut-être
adapter le "n" au moment de la réécriture.



J'ai du mal à voir comment ça marche. Je vais faire tourner le truc,
puisque je me remets à faire un peu de PHP, donc que je traîne dans le
coin.

Puisque je corrige, j'ajoute:
J'ai quand même fait tourner le truc, et effectivement, il me semble
que ça ne trie pas sur le second niveau. A moins que je n'ai pas pigé
l'énoncé...

En python, pas particulièrement compact, on doit pouvoir faire proche
en PHP:

tri1 = lambda x, y: cmp(int(y.split('(')[-1].rstrip()[:-1]),
int(x.split('(')[-1].rstrip()[:-1]))
tri2 = lambda x, y: cmp(int(y.split(':')[0]), int(x.split(':')[0]))
tri = lambda x, y: tri1(x, y) or tri2(x, y)

s = open('in.txt', 'r').readlines().sort(cmp=tri)
open('out.txt', 'w').write(''.join(s))

Correction:

...

s = open('in.txt', 'r').readlines()
s.sort(cmp=tri)
open('out.txt', 'w').write(''.join(s))

--
Pierre Maurette
loiseauthierry
Le #11190411
Thierry Loiseau
Bonjour, petit devoir de vacacances :)



Merci à vous de vous prêter au jeu par vos cogitations !!!
(mais je ne connais pas de bonnes solutions)

:((

Thierry
loiseauthierry
Le #11192951
Thierry Loiseau
Merci à vous de vous prêter au jeu par vos cogitations !!!
(mais je ne connais pas de bonnes solutions)



... bon je n'y arrive pas ! Pas facile, je n'ai pas PHP5 à la maison,
aussi...

Comment, plutôt que de créer un fichier de sortie, afficher le résultat
à l'écran !

Bonne fin de nuit :)

zzzzZZZzzz
--
* * __*__ *
* * * -----oOOo---°O°---oOOo------ * *
* * -------- oOOo oOOo -------- *
SAM
Le #11196191
Thierry Loiseau a écrit :

Comment, plutôt que de créer un fichier de sortie, afficher le résultat
à l'écran !

Bonne fin de nuit :)



Heu, après la sieste, j'imagine qu'on fait qque chose comme :

function cmp($a, $b)
{
preg_match("/([0-9]+).[rn]*$/", $a, $ma);
preg_match("/([0-9]+).[rn]*$/", $b, $mb);
return $mb[1] - $ma[1]; // b - a car ordre inverse
}
$contenu = file($inputfile);
usort($contenu, 'cmp');

$contenu = explode(/nr/, $contenu); // tableau (array) des lignes
foreach($contenu as $ligne) echo $ligne.'<br>';


Comme Olivier je te laisse tester ;-)
En particlier, peut-être faut-il : explode("nr", $contenu);


Peut-être aussi tout simplement :

<pre>
<?php
$contenu = file($inputfile);
usort($contenu, 'cmp');
printf($contenu);
?>
</pre>

avec ses 72351 fonctions, ce php nous offre trop de possibilités.

Autant, echo ou print feront le job ?

--
sm
Jacques Haddi
Le #11197021
> Comment faire pour réordonner ceci, réenregistrer dans un autre fichier
texte de telle sorte que la première ligne représente le numéro le plus
grand qui se trouve entre parenthèses et en sous-ordre, le numéro se
trouvant en début de la ligne ?



je propose :

<?
function compare($a, $b)
{
ereg("([0-9]+)","$a",$ta);
ereg("([0-9]+)","$b",$tb);
$a2=str_replace(")","",str_replace("(","",$ta[count($ta)-1]));
$b2=str_replace(")","",str_replace("(","",$tb[count($tb)-1]));
if ($a2==$b2)
{
$a1=intval($a);
$b1=intval($b);
if($a1==$b1)
{
return 0;
}
else
{
return ($a1 > $b1) ? -1 : 1;
}
}
else
{
return ($a2 > $b2) ? -1 : 1;
}
}
usort ($tab=file("fichier_texte.txt"), "compare");
fputs(fopen("fichier_texte_2.txt","w"), implode("", $tab));
?>

J.H.
Publicité
Poster une réponse
Anonyme