Trier les lignes d'un fichier texte

Résolu
haddreezy Messages postés 40 Date d'inscription lundi 14 mai 2012 Statut Membre Dernière intervention 8 août 2012 - 4 juil. 2012 à 10:22
Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 - 20 févr. 2018 à 17:16
Bonjour,

Pour un projet, j'écris dans un fichier texte. Mes lignes sont organisées ainsi: nom puissance distance temps
Simplement quand j'écris dans mon fichier texte, mes lignes ne sont pas ordonnées, je voudrais qu'elles soient écrites par ordre croissant des distances.
J'ai donc pensé à stocker d'abord mes lignes, qui sont des string, dans une liste, puis trier la liste en comparant les distances. Mais c'est la que je bloque.
Je pensais utiliser la méthode Sort(), mais la définition de ma comparaison pose problème. J'avais l'intention de comparer deux lignes, les splitter pour accéder à mes distances, les convertir en double pour pouvoir les comparer, et donc dire quelle ligne est "plus grande" que l'autre. Mais je ne m'en sort pas. merci pour votre aide.

9 réponses

krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
4 juil. 2012 à 14:01
Salut

Voici une méthode simple et très rapide à coder (pas extrêmement performante cependant) :

List<string> liste = new List<string>();

// Le mot-clé using permet de fermer automatiquement le fichier à la fin du bloc
using (StreamReader reader = new StreamReader(@"monFichier.txt"))
{
    string ligne;
    // Tant qu'on n'est pas à la fin du fichier, on ajoute les lignes une par une à la liste
    do
    {
        ligne = reader.ReadLine();
        if (!string.IsNullOrEmpty(ligne)) liste.Add(ligne);
    } while (ligne != null);
}

// Là, je trie les lignes de ma liste
// Le tri se fait en fonction de la valeur entière (Convert.ToInt32) de la troisième case ([2]) 
// de la ligne (element) splittée sur les espaces (.Split(' '))
IOrderedEnumerable<string> listeOrdonnee liste.OrderBy(element> Convert.ToInt32(element.Split(' ')[2]));

// Puis je sauvegarde
using (StreamWriter writer = new StreamWriter(@"monFichier.txt"))
{
    foreach (string ligne in listeOrdonnee)
    {
        writer.WriteLine(ligne);
    }
}


Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
3
bonjour,
je suis moins que débutante j'ai utilisé votre code, mais suis en erreur sur liste de liste.OrderBy dans la phrase : IOrderedEnumerable<string> listeOrdonnee liste.OrderBy(element> Convert.ToInt32(element.Split(' ')[2]));

vous pouvez m'orienter ? merci
0
Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 656 > nath
20 févr. 2018 à 10:44
Bonjour,
Quelle erreur?
Quel est le contenu des variables au moment où ça plante?
0
bonjour pas a l'exécution, je ne compile pas.
0
Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 656 > nath
20 févr. 2018 à 13:27
OK, le texte de l’erreur serait bien pratique.
0
; expected (CS1002) -
0
Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 656
4 juil. 2012 à 14:05
Bonjour,

tu peux te creer une classe (MaClasse) qui a comme propriétés nom, puissance, distance et temps. Tu stockes chaque ligne dans une instance de cette classe et chaque instance dans une List<MaClasse> (suivant ton message je pense que tu as déjà plus ou moins fait ça).

Pour pouvoir utiliser la méthode Sort de List<MaClasse>, il faut que MaClasse implémente l'interface IComparable<MaClasse>

    public class MaClasse: IComparable<MaClasse>
    {

Si tu fais un click doirt sur IComparable, la premiere ligne du menu contextuel sera "implémenter l'interface -> Implementer explicitement". Clique là dessus et ça va t'écrire un bout de code par défaut, dans lequel tu vas décrire comment trier tes données.

Dans la méthode CompareTo, il faut que tu retourne un entier 1 pour je suis plus grand, 0 pour je suis égal et -1 pour je suis plus petit.

Dans ton cas:
        int IComparable<MaClasse>.CompareTo(MaClasse other)
        {
            return Distance.CompareTo(other);
        }



Whismeril
3
cs_BinKentsu Messages postés 64 Date d'inscription jeudi 1 septembre 2011 Statut Membre Dernière intervention 22 juillet 2014 8
4 juil. 2012 à 11:19
Bonjour,
Si tu veux effectuer un tri dans un fichier texte, je pense que tu auras du boulot :s
Si j'étais toin j'aurai créé une petit base de données, et le trie aurait été fait en une ligne.
Réfléchie voir à cette option.

BinKentsu
0
cs_L0ci Messages postés 224 Date d'inscription vendredi 26 novembre 2010 Statut Membre Dernière intervention 11 juin 2013 7
4 juil. 2012 à 12:20
Bonjour,

Si toutes les valeurs de tes distances sont différentes tu pourrai (je n'ai pas test) utiliser un
Dictionary<distance, string>
en récupérant les distances de chaque string a la lecture de ton fichier.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
4 juil. 2012 à 14:03
Je dis "pas très performante", je veux dire qu'elle risque de prendre quelques centièmes de seconde de plus que si on l'avait optimisée.

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
0
Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 656
4 juil. 2012 à 14:07
Salut Krimog,
2 posts le temps que j'en tape 1, t'es trop rapide!!

Whismeril
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
4 juil. 2012 à 14:31
Hey, tu peux pas test !
(Je rassure les filles : je sais prendre mon temps pour d'autres choses).

En revanche, une petite erreur s'est glissée dans ton dernier code :
int IComparable<MaClasse>.CompareTo(MaClasse other)
{
    return Distance.CompareTo(other.Distance);
}
(C'est mieux avec le ".Distance" )

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
0
haddreezy Messages postés 40 Date d'inscription lundi 14 mai 2012 Statut Membre Dernière intervention 8 août 2012 4
4 juil. 2012 à 16:07
Bonjour,

Merci à tous pour vos messages. J'ai finalement réussi mon tri avant de voir vos messages :D J'ai utilisé la même méthode que Whismeril. J'ai créé une classe avec ses attributs correspondant à une ligne de mon fichier, ajouté les lignes dans une liste, puis trier la liste avec IComparable. En cas de d'égalité entre les distances, je compare mes lignes avec le temps:

class Ligne
{
//private string name;
//private double strength;
//private double distance;
//private double time;
public string Name { get; set; }
public double Strength { get; set; }
public double Distance { get; set; }
public double Time { get; set; }
}


private static int Compare(Ligne l1, Ligne l2)
{
if (l1 == null)
{
if (l2 == null)
{
// If l1 is null and l2 is null, they're
// equal.
return 0;
}
else
{
// If l1 is null and y is not null, l2
// is greater.
return -1;
}
}
else
{
// If l1 is not null...
//
if (l2 == null)
// ...and l2 is null, l1 is greater.
{
return 1;
}
else
{
// ...and l2 is not null, compare the
// distance of the two lines.
//
int retval = l1.Distance.CompareTo(l2.Distance);

if (retval != 0)
{
// If the lines are not of equal distance,
// the longer line is greater.
//
return retval;
}
else
{
// If the liness are of equal distance,
// sort them with ordinary line comparison.
//
return l1.Time.CompareTo(l2.Time);
}
}

}
}
Une fois les lignes ajoutées et triées je les réécris dans un fichier et le tour est joué. Merci encore.
0
Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 656
4 juil. 2012 à 19:31
@Krimog

(C'est mieux avec le ".Distance" )


bien vu

Whismeril
0
Rejoignez-nous