2008-12-21 5 views
4

Y a-t-il un moyen intégré pour limiter la profondeur d'un System.Collection.Generics.Stack? Donc, si vous êtes à la capacité maximale, pousser un nouvel élément enlèverait le bas de la pile?Puis-je limiter la profondeur d'une pile générique?

Je sais que je peux le faire en se convertissant à un tableau et la reconstruction de la pile, mais j'ai pensé il y a probablement une méthode sur déjà.

EDIT: J'ai écrit une méthode d'extension:

public static void Trim<T> (this Stack<T> stack, int trimCount) 
    { 
     if (stack.Count <= trimCount) 
      return; 

     stack = new 
      Stack<T> 
      (
       stack 
        .ToArray() 
        .Take(trimCount) 
      );   
    } 

Ainsi, il retourne une nouvelle pile sur la coupe, mais n'immuabilité la voie fonctionnelle =)

La raison est que je stocke des étapes d'annulation pour une application dans une pile, et je veux seulement stocker un nombre fini d'étapes.

+0

Ce n'est pas une vraie pile si vous implémentez votre comportement. Le comportement le plus correct est probablement de lancer une exception ou (dans les systèmes concurrents) bloquer jusqu'à ce que l'espace soit disponible (en supposant que le thread actuel n'est pas le seul thread à pousser sur la pile). – cletus

+0

Ma première pensée est que vous ne faites pas une faveur à vos utilisateurs de cette façon. –

+2

Jay, Élaborer? Comment stockez-vous les informations d'annulation de profondeur limitée? – FlySwat

Répondre

1

Je ne peux pas voir un moyen. Vous pouvez hériter de Stack<T>, mais il ne semble pas y avoir d'élément utile à remplacer.

Le moyen facile (si un peu fastidieux) serait d'envelopper le Stack<T> dans votre propre, par exemple, LimitedStack<T>. Ensuite, implémentez les méthodes que vous voulez et passez à un Stack<T> interne, tout en incluant votre logique de limitation dans la méthode Push et partout où vous en avez besoin.

Il est difficile d'écrire tous ces membres directs, surtout si vous implémentez toutes les mêmes interfaces que Stack<T> ... mais d'un autre côté, vous n'avez qu'à le faire une fois et c'est fait.

1

Je crois que vous êtes à la recherche d'un (éventuellement modifié) dequeue - la structure de données qui permet d'accéder à partir de chaque extrémité.

+1

Je ne sais pas pourquoi cela a été downvoted - ressemble à une solution parfaitement raisonnable pour moi. –

16

Ce que vous cherchez s'appelle une pile . AFAIK, la BCL n'en contient pas, bien qu'elles soient triviales à mettre en œuvre. Généralement, la fonctionnalité Annuler et Rétablir repose sur ces structures de données.

Ils sont essentiellement un tableau, et lorsque vous appuyez sur la pile le « top » de la pile se déplace autour du tableau. Finalement, le haut reviendra au début lorsque la pile est pleine et remplacera le 'bas' de la pile.

Google n'a pas fourni beaucoup d'information là-dessus. C'est le meilleur que je pouvais trouver:

(PDF Avertissement) http://courses.cs.vt.edu/~cs2704/spring04/projects/DropOutStack.pdf

est ici un code de plaque de la chaudière, pour démarrer. Je vous laisse remplir le reste (vérifier la santé mentale, compte, indexeur, etc.)

class DropOutStack<T> 
{ 
    private T[] items; 
    private int top = 0; 
    public DropOutStack(int capacity) 
    { 
     items = new T[capacity]; 
    } 

    public void Push(T item) 
    { 
     items[top] = item; 
     top = (top + 1) % items.Length; 
    } 
    public T Pop() 
    { 
     top = (items.Length + top - 1) % items.Length; 
     return items[top]; 
    } 
} 
3

Vous cherchez réellement à quelque chose de similaire à la mise en œuvre de la liste circulaire. Il y a une implémentation LimitedQueue effectuée par PIEBALDconsult à CodeProject. C'est semblable à votre exigence. Vous avez juste besoin d'envelopper Stack au lieu de Queue comme fait par l'auteur. De plus, l'auteur a également implémenté l'indexeur, ce qui est pratique si vous avez besoin d'accéder à autre chose que la pile supérieure (pour afficher la liste d'annulation peut-être).

EDIT: L'implémentation de l'auteur déclenche également un événement lorsque le dernier (le premier, selon qu'il s'agit d'une file d'attente ou d'une pile) est supprimé, afin que vous sachiez quand quelque chose est rejeté.

Questions connexes