11
votes

Comment puis-je utiliser C # pour trier les valeurs numériquement?

J'ai une chaîne contenant des nombres séparés par des périodes. Quand je trie, il apparaît comme ça puisqu'il s'agit d'une chaîne: (ordre de charme ASCII) xxx

etc.

Je veux que cela trite comme ceci: (en ordre numérique ) xxx

Je sais que je peux:

  1. Utilisez la fonction Split pour obtenir les numéros individuels
  2. mettre les valeurs dans un objet
  3. Trier l'objet

    Je préfère éviter tout ce travail s'il fait dupliquer les fonctionnalités existantes. Est une méthode dans le cadre .NET qui fait déjà cela?


4 commentaires

Pouvez-vous être plus clair sur ce que vous voulez? Quelle est la différence entre le tri que vous obtenez et le genre que vous voulez?


Il veut qu'ils ordonnaient à l'ordre croissant selon l'exemple donné, 10 suit donc 9 au lieu de la suite 1.


Je pense que Tarzan a une liste de données dans l'ordre de caractère et le veut trier par ordre numérique.


Voyant comment il n'a pas pris la peine de trimer sur la pléthore des réponses, je ne me dérangerai pas de demander quel son problème est de fracler la chaîne. Ce n'est pas un "travail supplémentaire" et fonctionne dans le temps O (n).


9 Réponses :


3
votes

Non, je ne crois pas qu'il y ait quelque chose dans le cadre qui le fait automatiquement. Vous pouvez écrire votre propre icomparer tandis que ne le fait pas ne divise-t-il pas, mais itère plutôt sur les deux cordes, ne comparant que autant que nécessaire (c'est-à-dire simplement. Le premier nombre de chacun, puis continuant si nécessaire, etc.) mais ce serait assez fidèle que je soupçonne. Il aurait également besoin de faire des hypothèses sur la manière dont "1.2.3.4.5" par rapport à "1.3" par exemple (c'est-à-dire où les valeurs contiennent des nombres différents de nombres).


1 commentaires

Ma solution fait tout ce que vous expliquez.



2
votes

Comme la comparaison que vous souhaitez faire sur les chaînes est différente de la manière dont les chaînes sont normalement comparées dans .NET, vous devrez utiliser un comparateur de chaîne de chaîne personnalisé

var sorted = lst.OrderBy(s => s, new MyStringComparer());

lst.Sort(new MyStringComparer());


4 commentaires

Pas de Lambda? Peu décevant. Pourtant, c'est la solution la plus intéressante. +1


L'OP veut éviter la fractionnement de la chaîne.


Cela doit être fait d'une manière ou d'une autre. Il peut également utiliser Numstring.here (Char.isdigit) pour supprimer "". (point) de la chaîne, puis comparez les cordes de caractères par char.


Eh bien .. Le point est que la chaîne doit être analysée avant de pouvoir effectuer votre comparaison. Certains utilisent une division et une certaine sous-chaîne et index de. Mais l'analyse doit être faite quand même.



1
votes

est-il possible pour vous de taper vos champs à la même longueur sur le devant avec 0 ? Si tel est le cas, vous pouvez simplement utiliser le tri lexicographique droit sur les cordes. Sinon, il n'y a pas de telle méthode intégrée au cadre qui le fait automatiquement. Vous devrez mettre en place votre propre icomparer si le rembourrage n'est pas une option.


0 commentaires

0
votes

En plus de la mise en œuvre de votre propre IComparer en tant que mention JON, si vous appelez Tolist () sur votre matrice, vous pouvez appeler la méthode .sort () et passer dans un paramètre de fonction qui compare deux valeurs, comme indiqué ici: http://msdn.microsoft.com/en-us/library/w56d4y5z.aspx


1 commentaires

Je l'ai mentionné comme une alternative.



1
votes

Pas vraiment, bien que vous puissiez utiliser des regex ou LINQ pour éviter trop de réinventer des roues. Gardez à l'esprit que cela vous coûtera beaucoup de même de la même manière d'utiliser quelque chose intégré de manière à rouler votre propre.

Essayez ceci: xxx

pas le plus compact, mais Il devrait fonctionner et vous pourriez utiliser une combinaison Y-Combinator pour faire la comparaison A Lambda.


1 commentaires

On dirait assez cher et je trouve difficile de comprendre que ce que vous faites dans cette énoncé de choix, c'est simplement trier.




1
votes

diviser chaque chaîne par '.', itérale à travers les composants et les comparer numériquement.

Ce code suppose également que le nombre de composants est indiqué (une chaîne '1.1.1' sera supérieure à '2.1'. Ceci peut être ajusté en modifiant le premier si instruction dans la méthode correspondant ci-dessous. xxx


3 commentaires

L'OP veut éviter la fractionnement de la chaîne.


Ah. =) L'OP doit réévaluer ses priorités. La scission de la chaîne concerne l'opération la moins chère impliquée.


C'est aidez-moi à compléter 80% de mon tri merci :)



6
votes

Voici ma solution de travail qui s'occupe également des chaînes qui ne sont pas dans le bon format (par exemple contiennent du texte).

L'idée est d'obtenir le premier numéro dans les deux chaînes et de comparer ces numéros. S'ils correspondent, continuez avec le numéro suivant. S'ils ne le font pas, nous avons un gagnant. Si un si ces chiffres ne sont pas un nombre du tout, effectuez une comparaison de chaîne de la pièce, qui n'était pas déjà comparée.

Il serait facile de rendre le comparateur entièrement compatible avec l'ordre de tri naturel par Changer le moyen de déterminer le numéro suivant.

regarde ça .. vient de trouver Cette question .

le comparateur: xxx

usage: < / p> xxx

sortie: xxx


2 commentaires

Disons que nous avons des chiffres suivants 10 10.01 2 3 1.1 1.2 1 et je me déplace de la sortie: 1.1 1.2 1 2 3 10 10.01 pouvez-vous m'aider avec ça ?!


Cela fonctionne presque parfaitement. Mais des nombres non décimaux apparaîtront après des nombres décimaux. Ex: 4.01, 4.10, 4



1
votes

Vous pouvez utiliser l'awesome alphanumcomparator algorithme de tri naturel alphanum par David Koelle.

Code: xxx

Si vous allez utiliser la version C # modifie-la à: xxx

et xxx


0 commentaires