6
votes

C # - Le moyen le plus rapide de trier la gamme de primitives et de suivre leurs indices

J'ai besoin d'un float [] pour être trié. Et j'ai besoin de savoir où sont les anciens indices dans un nouveau tableau. C'est pourquoi je ne peux pas utiliser array.sort (); ou autre chose. Donc, je voudrais écrire une fonction qui trie le tableau pour moi et se souvient de quel index il a pris chaque valeur: xxx

taille des tableaux serait d'environ 500. Comment dois-je m'approcher? Quel algorithme de tri, etc.


après résolu:

Il me surprend toujours à quel point C # est puissant. Je n'ai même pas besoin de pouvoir faire cette tâche à sa propre tâche. Et puisque j'ai déjà entendu dire que array.sort () est très rapide, je vais le prendre.


3 commentaires

À propos des indices ... Ne serait-il pas plus facile de simplement enregistrer la liste d'entrée, trier la sortie, puis comparer les index entre les deux? Il n'y a pas de différence de taille dans la mémoire entre un flotteur et INT, de sorte que cela ne constitue pas votre mémoire.


@Tophe êtes-vous sûr que ce serait le moyen le plus rapide?


Pas sûr, et ce n'est pas aussi slick que la réponse acceptée. Mais en fonction de la fréquence à laquelle vous avez besoin, d'obtenir les index d'origine, il pourrait être plus efficace de comparer des index plutôt que de boucler à chaque liste de la création - car la liste d'entrée contient déjà les index d'origine. Cela vous donne une instruction de moins à faire à chaque fois. Probablement, cependant, vous aurez une manière plus douce de saisir les valeurs d'autres moyens.


5 Réponses :


5
votes

Vous pouvez utiliser la surcharge de Array.Sort () qui prend deux tableaux et trie le second en fonction de la triée de la première:

float[] input  = new [] { 1.5f, 2, 0, 0.4f, -1, 96, -56, 8, -45 };
int[] indices = Enumerable.Range(0, input.Length).ToArray();
Array.Sort(input, indices);


0 commentaires

4
votes

Vous pouvez créer une nouvelle gamme d'indices, puis trier les deux à l'aide d'Array.sort et de traitement entrée comme clé: xxx


0 commentaires

12
votes
float[] input = new float[] { 1.5F, 2, 0, 0.4F, -1, 96, -56, 8, -45 };
int[] indices = new int[input.Length];
for (int i = 0; i < indices.Length; i++) indices[i] = i;
Array.Sort(input, indices);
// input and indices are now at the desired exit state
Basically, the 2-argument version of Array.Sort applies the same operations to both arrays, running the actual sort comparisons on the first array. This is normally used the other way around - to rearrange something by the desired indices; but this works too.

3 commentaires

Merci d'un exemple sans Linq et avec une bonne explication.


Une liste > et une trieuse personnalisée fonctionnerait également


@tinstafl mais serait plus compliqué, nécessite une duplication des données d'origine (note que je n'ai jamais dupliqué les flotteurs); ne trierait pas réellement le tableau d'origine; et serait moins direct (via le comparateur) et donc je voudrais attendre moins performant (non vérifié)



0
votes

Si vous utilisez LINQ:

    float[] input = new float[] { 1.5F, 2, 0, 0.4F, -1, 96, -56, 8, -45 };

    var result = input.Select(x => new { Value = x, Index = input.ToList().IndexOf(x)}).OrderBy(x => x.Value).ToList();

    // sort
    float[] output = result.Select(x => x.Value).ToArray();
    int[] indices = result.Select(x => x.Index).ToArray();


1 commentaires

Vous réalisez que cela fait un entrée.tolist par élément d'entrée et ne donne pas les résultats corrects s'il y a des doublons? Il y a en fait une surcharge de SELECT que mains vous L'index de chaque élément - .Sélectionnez ((x, i) => nouvelle {valeur = x, index = i}) serait beaucoup mieux. Mais dans ce cas, array.sort est tout ce qui est nécessaire, de toute façon.



0
votes

une liste > code> et une trieuse personnalisée fonctionnerait également. La clé de chaque paire détient l'index d'origine.

    private void Form1_Load(object sender, EventArgs e)
    {           
        List<KeyValuePair<int,float>> data = new List<KeyValuePair<int,float>>
        {
             new KeyValuePair<int,float>(0,1.5f),
             new KeyValuePair<int,float>(1,2),
             new KeyValuePair<int,float>(2,0),
             new KeyValuePair<int,float>(3,0.4f),
             new KeyValuePair<int,float>(4,-1),
             new KeyValuePair<int,float>(5,96),
             new KeyValuePair<int,float>(6,-56),
             new KeyValuePair<int,float>(7,8),
             new KeyValuePair<int,float>(8,-45)
        };
        data.Sort(SortByValue);
        foreach (KeyValuePair<int, float> kv in data)
        {
            listBox1.Items.Add(kv.Key.ToString() + " - " + kv.Value.ToString());
        }


    }
    private int SortByValue(KeyValuePair<int, float> a, KeyValuePair<int, float> b)
    {
        return a.Value.CompareTo(b.Value);
    }


0 commentaires