Trier les lignes d'un fichier texte [Résolu]

Signaler
Messages postés
40
Date d'inscription
lundi 14 mai 2012
Statut
Membre
Dernière intervention
8 août 2012
-
Messages postés
15933
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 mai 2021
-
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

Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
44
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é. -
Messages postés
15933
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 mai 2021
545 > nath
OK, le texte de l’erreur serait bien pratique.
; expected (CS1002) -
Messages postés
15933
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 mai 2021
545 > nath
Essaye ça, j’ai tapé de tête.
IOrderedEnumerable<string> listeOrdonnee = liste.OrderBy(element => Convert.ToInt32(element.Split(' ')[2])); 
merci infiniment

c'est mon premier c#, je galère.
Messages postés
15933
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 mai 2021
545 > nath
Ce message a été écrit, avant 2 changements majeurs du site, il est possible que l'un des 2 ait fait disparaitre les =
Messages postés
15933
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 mai 2021
545
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
Messages postés
65
Date d'inscription
jeudi 1 septembre 2011
Statut
Membre
Dernière intervention
22 juillet 2014
7
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
Messages postés
224
Date d'inscription
vendredi 26 novembre 2010
Statut
Membre
Dernière intervention
11 juin 2013
7
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.
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
44
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é. -
Messages postés
15933
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 mai 2021
545
Salut Krimog,
2 posts le temps que j'en tape 1, t'es trop rapide!!

Whismeril
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
44
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é. -
Messages postés
40
Date d'inscription
lundi 14 mai 2012
Statut
Membre
Dernière intervention
8 août 2012
4
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.
Messages postés
15933
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 mai 2021
545
@Krimog

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


bien vu

Whismeril