2010-10-06 3 views
4

J'ai une méthode qui permute deux éléments:échange commandé sur simple collection

swap(collection['a'], collection['b']); // result = 'b', 'a' 
swap(collection[0], collection[1]); // result = collection[1], collection[0] 
swap(0, collection.indexOf(collection[1])); // result collection[1] index, 0 
  • La méthode d'échange ne peut pas être modifié.
  • Quatre valeurs possibles stockées dans une collection: 'a', 'b', 'c', 'd'
  • Échangées pour toujours être dans cet ordre 'd', 'b', 'a', 'c' '
  • un quelconque des quatre valeurs possibles peuvent ou peuvent ne pas être dans la collection

S'il vous plaît aidez-moi à mettre en œuvre cet algorithme.

Merci!

Pour ceux qui s'en soucient, ce n'est pas un devoir.

Exemples:

//Example 1: 
//collection contains: 'a', 'b', 'c', 'd' 
//desired order: 'd', 'b', 'a', 'c' 
swap(0, collection.IndexOf(collection['d'])); 
swap(1, collection.IndexOf(collection['b'])); 
swap(2, collection.IndexOf(collection['a'])); 
swap(3, collection.IndexOf(collection['c'])); 

//Example 2: 
//collection contains: 'a', 'b', 'c' 
//desired order: 'b', 'a', 'c' 
swap(0, collection.IndexOf(collection['b'])); 
swap(1, collection.IndexOf(collection['a'])); 
swap(2, collection.IndexOf(collection['c'])); 
+0

Est-ce devoir? Qu'essayez-vous de faire? Pouvez-vous donner un exemple de la façon dont il pourrait être utilisé? –

+0

Je crois que la question devrait répondre à vos questions. –

Répondre

0

Je me rends compte maintenant (merci à ceux qui ont répondu) que l'utilisation d'un IComparer personnalisé comme ci-dessous supprime le besoin d'utiliser swap. Cette solution garantit la commande et fonctionnera toujours correctement lorsque l'une des 5 valeurs possibles est manquante.

class CustomOrder : IComparer<Series> 
{ 
    static readonly Dictionary<string, int> dictionary = 
     new Dictionary<string, int>() 
    { 
     {"Excellent", 1}, 
     {"Very Good", 2}, 
     {"Average", 3}, 
     {"Bad", 4}, 
     {"Very Bad", 5} 
    }; 

    public int Compare(Series x, Series y) 
    { 
     return dictionary[x.Name].CompareTo(dictionary[y.Name]); 
    } 
} 

public partial class _Default : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     Series[] sortedSeries = chart.Series.ToArray(); 
     Array.Sort(sortedSeries, new CustomOrder()); 
    } 
} 

Ancienne solution à l'aide swap (pour référence)

Je ne l'aime pas, mais cela semble fonctionner. Quelqu'un a-t-il de meilleures idées?

int count = collection.Count; 

// don't need to swap if there is only one element 
if (count > 1) 
{ 
    // have to run once for each letter 
    sortCollection(count); 
    sortCollection(count);  
    sortCollection(count); 
    sortCollection(count); 
} 

private void sortCollection(int count) 
{ 
    if (collection.Contains(collection['c'])) 
    { 
     // take care of last element 
     collection.Swap(count - 1, collection.IndexOf(collection['c'])); 
    } 
    if (collection.Contains(collection['a']) && collection.Contains(collection['b'])) 
    { 
     // take care of middle elements 
     if(collection[1] != collection['b']) 
     collection.Swap(collection['a'], collection['b']); 
    } 
    if (collection.Contains(collection['d'])) 
    { 
     // take care of first element 
     if(collection[0] != collection['d']) 
     collection.Swap(0, collection.IndexOf(collection['d'])); 
    } 
} 
+0

Dans certains endroits, vos indices sont des entiers compris entre 0 et 4, et dans d'autres endroits, vos indices sont des caractères «a» à «d». Est-ce vraiment comment votre collection peut être indexée - les deux façons? –

+0

Oui. La collection peut être indexée sur un entier ou une chaîne (bien que j'ai utilisé le caractère dans l'exemple) –

2

Fondamentalement, vous êtes à la recherche d'une sorte avec une comparaison indirecte. C'est-à-dire, au lieu de comparer les lettres elles-mêmes, vous comparez les valeurs qu'elles recherchent dans un tableau. Si vous pardonnerez la syntaxe de C, l'idée générale serait quelque chose comme ceci:

class my_cmp { 
    static const int positions[] = { 2, 1, 3, 0}; 
public: 
    bool operator<(char a, char b) { 
     return positions[a-'a'] < positions[b-'a']; 
    } 
}: 

std::sort(collection.begin(), collection.end(), my_cmp()); 

std::sort utilisera swap pour déplacer les éléments de la collection. Bien que la syntaxe soit évidemment un peu différente, d'après ce dont je me souviens quand je l'ai utilisé pour la dernière fois, la même idée générale devrait s'appliquer aussi bien à C#.

2

Jerry C++ solution adaptée à C#:

using System; 
using IComparer = System.Collections.IComparer; 

class CustomOrder: IComparer 
{ 
    static readonly int[] positions = { 2, 1, 3, 0 }; 

    public int Compare(object x, object y) 
    { 
     return positions[(char)x-'a'].CompareTo(positions[(char)y-'a']); 
    } 
} 

class Startup 
{ 
    static void Main(string[] args) 
    { 
     char[] collection = {'a', 'b', 'c', 'd'}; 

     Console.WriteLine(collection);   // abcd 
     Array.Sort(collection, new CustomOrder()); 
     Console.WriteLine(collection);   // dbac 
    } 
} 
+0

Pourriez-vous mettre à jour ceci pour pouvoir utiliser une chaîne à la place d'un caractère? J'ai utilisé des données simples dans ma question, mais en réalité les données que j'ai besoin de trier sont de type données. Merci. –

+0

Remplacez simplement 'char' par' chaîne', et vous devrez peut-être changer les guillemets simples en guillemets doubles (cela fait longtemps que je n'ai rien fait de C#, donc je ne me souviens pas de sa syntaxe détaillée). Je pense que la chose difficile à faire est de faire de cette utilisation un «échange» personnalisé, par exemple. si vous voulez voir quels swaps sont exécutés.Je ne pouvais pas voir un moyen facile de faire de la méthode 'Sort' un échange personnalisé, ou de quelque façon que ce soit. Mais comme il y a très peu d'éléments, un tri d'insertion codé à la main serait assez efficace. C'est comme, pour chaque valeur, insérez-le à sa bonne position. Cheers & hth., –

+0

Ce n'est pas si simple. Vous ne pouvez pas soustraire un entier d'une chaîne, dans les langages basés sur C. –