Comment mettre en œuvre trois piles à l'aide d'un tableau unique
Je suis tombé sur ce problème dans une interview site web. Le problème demande pour mettre efficacement en œuvre les trois piles dans un tableau unique, de sorte qu'aucune débordements de pile jusqu'à ce qu'il n'y a pas d'espace à gauche dans le tableau d'ensemble de l'espace.
Pour la mise en œuvre de 2 piles dans un tableau, il est assez évident: 1ère pile augmente de GAUCHE à DROITE, et la 2ème pile augmente de DROITE à GAUCHE; et quand le stackTopIndex traverse, il signale un dépassement de capacité.
Merci d'avance pour votre réponse perspicace.
Ah, c'est très bien étudié le problème de la " au début des années 70 (ou peut-être plus tôt). En essayant de se rappeler où j'ai vu ce. Knuth? Sedgewick? Standish? Hmm... je pense que Knuth en particulier, ont mentionné un truc/heuristique pour favoriser la croissance rapide de la pile (de N de piles, de 3 dans votre cas), mais ne peuvent pas facilement se rappeler 🙂
Ah, trouvé il, ajoutant que la réponse ci-dessous.
quoi de la demande de faire 3 piles de tableau unique? réel besoin?
La localité de référence. Si nous prenons les trois piles, leur mémoire sera alloué à des endroits différents, de sorte qu'ils pourraient ne pas être dans la mémoire physique (RAM) en même temps. Et, pourrions-nous avoir la page miss.. et devrez apporter la nouvelle de la pile de disque RAM. Alors que, dans le cas de 3 pile comme un tableau de mise en œuvre, le plus souvent, toutes les piles seront sur une seule page, et toutes les piles seront dans la RAM, même si une seule pile est le plus fréquemment utilisé, et d'autres sont utilisés moins souvent.
Ah, trouvé il, ajoutant que la réponse ci-dessous.
quoi de la demande de faire 3 piles de tableau unique? réel besoin?
La localité de référence. Si nous prenons les trois piles, leur mémoire sera alloué à des endroits différents, de sorte qu'ils pourraient ne pas être dans la mémoire physique (RAM) en même temps. Et, pourrions-nous avoir la page miss.. et devrez apporter la nouvelle de la pile de disque RAM. Alors que, dans le cas de 3 pile comme un tableau de mise en œuvre, le plus souvent, toutes les piles seront sur une seule page, et toutes les piles seront dans la RAM, même si une seule pile est le plus fréquemment utilisé, et d'autres sont utilisés moins souvent.
OriginalL'auteur user369070 | 2010-06-17
Vous devez vous connecter pour publier un commentaire.
Vous pouvez mettre en œuvre trois piles avec un liste:
Un liste liée peut être mise en œuvre dans un tableau.
Comment (espace) efficace?
Il n'est pas un problème pour construire une liste liée par l'utilisation de deux cellules d'un tableau pour chaque élément de la liste (valeur + pointeur). En fonction de la spécification que vous pourriez même obtenir de pointeur et de la valeur à un élément de tableau (par exemple, le tableau est long, la valeur et le pointeur ne sont int).
Comparez cela à la solution de kgiannakakis ... où vous perdre jusqu'à 50% (seulement dans le pire des cas). Mais je pense que ma solution est un peu plus propre (et peut-être plus académique, qui devrait être pas un handicap pour une question d'entrevue ^^).
La question n'est pas de dire quel est le type du tableau est ou les valeurs que vous avez besoin de stocker. Si vous suppose de votre pile pour stocker des nombres de 32 bits et que vous créez un tableau de 64 bits vous pouvez facilement le pack de la liste liée pointeurs vers le haut/bits de poids faible de chaque tableau de la valeur.
oui cela dépend de la spécification - vous toujours besoin d'un peu d'espace pour votre pointeurs. Mais mon point est qu'une double liaison de la liste est essentiellement une structure de données adéquate à ce problème. Vous vous l'utilisez pour la mise en œuvre n'est pas difficile plus.
Pourquoi le "double" liens? Une pile est toujours parcourue dans le même sens ...
Vous êtes de droite. L'idée est d'utiliser un 4ème pointeur pour une liste d'éléments. J'ai mis à jour ma réponse ... ^^ thx
OriginalL'auteur tanascius
Voir Knuth, The Art of Computer Programming, Volume 1, La Section 2.2.2. intitulé "attribution Séquentielle". Traite de l'allocation de plusieurs files d'attente/piles dans un tableau unique, avec des algorithmes traitant avec les débordements, etc.
Par ailleurs, les meilleures réponses sont déjà englobé dans Knuth est beaucoup plus traitement approfondi de ce problème. Just sayin'.
Peut-être que la personne n'a pas été downvoting Knuth, mais une réponse qui est pratiquement inutile si vous n'avez pas encore le livre à la maison (dans ce cas, vous ne seriez pas intéressé à la question, en premier lieu, je suppose).
Comment sur les bibliothèques. Je ne me souviens pas la dernière fois, quand j'ai vécu à un endroit sans une bibliothèque Knuth.
Salut, avez-vous l'esprit l'affichage de la partie d'en parler ? Au moins l'idée de celui-ci
OriginalL'auteur Dimitris Andreou
Nous pouvons utiliser à long tableau de bits représentant de, qui mettent à la i-ième de la matrice de cellule appartient.
On peut prendre des valeurs par modulo 3 (00 - vide, 01 - A, 10 - B, 11 - C). Il faudrait N/2 bits ou N/4 octets de la mémoire supplémentaire pour N tableau de taille.
Par exemple pour une résolution 1024 long int éléments (4096 octets) il faudra que 256 octets, ou de 6%.
Ce tableau de bits de la carte peut être placé dans le même tableau, au début ou à la fin, juste de la réduction de la taille du tableau donné par la constante de 6%!
Devrait lire: "N*2 bits ou N/4 octets"?
Je suis assez sûr que pour la pile de profondeur
N
, il va prendreN log₃ / log₂ ≈ N ⋅ 1.585
des bits supplémentaires. I. e. pour les éléments avec la taille1
peu cette image bitmap ont une surcharge+158%
, pour les éléments de la gamme0..2
il aura des frais généraux+100%
, pour les octets de long+20%
. Pour obtenir plus qu'+6%
la taille de l'élément doit être d'au moins27
bits ou de la plage ~0 .. 89 540 788
.comment ce différent de stackoverflow.com/a/3075233/230744 ? (à l'exception des calculs bizarres)
OriginalL'auteur Vitamon
Première pile augmente de la gauche vers la droite.
Deuxième pile augmente de droite à gauche.
Troisième pile commence à partir du milieu. Supposons que l'étrange tableau de taille pour des raisons de simplicité. Puis de troisième pile grandit comme ceci:
Première et deuxième piles sont autorisés à se développer au maximum à la moitié de la taille de la matrice. La troisième pile peut croître jusqu'à remplir tout le tableau à un maximum.
Pire des cas, c'est quand l'un des deux premiers tableaux pousse à 50% de la matrice. Puis il y a 50% des déchets de la matrice. Pour optimiser l'efficacité de la troisième tableau doit être sélectionné pour être l'un qui pousse plus vite que les deux autres.
Mais supposons que la 1ère pile contient 1 entrée, 2ème pile dispose de 4 entrées. Où avez-vous mis 3ème de la pile de la 4e entrée?
Les deux d'entre vous sont à droite. Ma solution peut perdre jusqu'à 50%. Je serai intéressé de voir si quelqu'un peut proposer une meilleure solution.
Je voulais parler de cette approche dans mon post initial. Mais comme l'auteur fait observer qu'il pourrait déchets de 50% de l'espace dans le pire des cas.
OriginalL'auteur kgiannakakis
C'est intéressant à énigme, et je n'ai pas de vraie réponse, mais penser légèrement à l'extérieur de la boîte...
cela pourrait dépendre de ce que chaque élément de la pile se compose de. Si c'est trois piles de vrai/faux drapeaux, alors vous pouvez utiliser les trois premiers bits de l'entier éléments. C'est à dire. le bit 0 est la valeur de la première pile, le bit 1 est la valeur de la deuxième pile, le bit 2 est la valeur de la troisième pile. Ensuite, chaque pile peut se développer de façon indépendante jusqu'à ce que l'ensemble du tableau est complet pour la pile. C'est encore mieux que les autres piles peuvent continuer à croître, même si le premier de la pile est pleine.
Je sais que c'est de la triche un peu et de ne pas vraiment répondre à la question, mais il fonctionne pour un cas très spécifique et pas d'entrées dans la pile sont gaspillés. Je suis de regarder avec intérêt de voir si quelqu'un peut venir avec une réponse adéquate qui fonctionne pour plus d'éléments génériques.
Le vrai et le bien repéré, donc, retour à la réflexion. Comme Damien l'a dit, elle dépend de toutes les positions de tableau doit être utilisé pour stocker des valeurs. Si oui, alors la double liaison-méthode de la liste (ce qui est probablement la bonne réponse, à partir d'une entrevue POV) ne peut pas être utilisé. Dans ce cas kgiannakakis réponse est probablement ok, mais de toute évidence des déchets jusqu'à 50% de l'espace. Nous sommes toujours en attente d'une réponse définitive qui utilise chaque élément d'une valeur et ne gâche pas tout l'espace. Damien n', mais il serait difficile de maintenir l'ordre de la pile lors du déplacement d'une extrémité du milieu de la pile à l'autre.
OriginalL'auteur giles123
Split tableau en 3 parties (peu importe si vous allez diviser de façon séquentielle ou entrelacé). Si une pile augmente de plus de 1/3 de la pile que vous commencez le remplissage des extrémités de repos de deux piles de la fin.
Le pire des cas, c'est quand deux piles pousse jusqu'à 1/3 de limite et puis, vous avez 30% de l'espace de déchets.
Lorsque "aaa" est complètement rempli de GAUCHE à DROITE, il commence à se remplir "bbb" et "ccc" simultanément (impair élément va à une pile et même aux autres) de la DROITE vers la GAUCHE jusqu'à ce qu'il a rencontré l'un des leur sommet. I. e. la longueur de la pile "aaa" est (n + (n - max (en haut("bbb"), haut("ccc"))). Quand vous frappez problème avec l'ajout d'un autre élément de la pile "aaa", ce qui signifie que la pile de disques pour "bbb" ou de "ccc" est entièrement rempli. Donc, si toutes les piles se développe avec la même vitesse ou une pile augmente avec la vitesse 2x ou deux avec 0x qu'aucun espace n'est perdu. Si il y a une pile 2x et d'autres 0x - vous obtiendrez (1/3)/2 espace gaspillé.
OriginalL'auteur ony
En supposant que toutes les positions de tableau doit être utilisé pour stocker des valeurs - je suppose que cela dépend de votre définition de l'efficacité.
Si vous ne les deux pile de solution, lieu de la troisième pile quelque part au milieu, et deux de ses bas et le haut, puis la plupart des opérations continuera à être efficace, à une peine d'une coûteuse opération de Déplacement (de la troisième pile vers où l'espace libre reste, se déplaçant vers le point à mi-chemin de l'espace libre) lorsqu'une collision se produit.
Ça va certainement être rapide au code et à comprendre. Quels sont nos objectifs d'efficacité?
OriginalL'auteur Damien_The_Unbeliever
Plutôt stupide mais efficace, la solution pourrait être:
i*3
positions: 0,3,6,...i*3+1
positions: 1,4,7...i*3+2
positions.Le problème avec cette solution est que la mémoire utilisée sera toujours trois fois la taille du plus profond de la pile et que vous pouvez dépassement de même lorsqu'il y a de postes disponibles à la gamme.
OriginalL'auteur Pablo Francisco Pérez Hidalgo
Faire une table de hachage avec des clés à la fin et de début de postes par exemple < "B1" , 0 >, <"E1" , n/3 >
pour chaque Push(valeur) ajouter une condition pour vérifier si la position de la Bx est antérieur Ex ou il ya quelques autres "Par" entre les deux. -- appelons cela la condition (2)
avec la condition ci-dessus à l'esprit,
si ci-dessus (2) est vraie //si B1 et E1 sont dans l'ordre
{ if ( S1.Push()), alors E1 ++ ;
else //condition de débordement ,
{ commencer à pousser à la fin de l'E2 ou E3 (selon ce qui a un espace) et mise à jour de E1 à E2-- ou E3-- ; }
}
si au-dessus de (2) est fausse
{ if ( S1.Push()), alors E1 -- ;
else //condition de débordement ,
{ commencer à pousser à la fin de l'E2 ou E3 (selon ce qui a un espace) et mise à jour de E1 à E2-- ou E3-- ; }
}
OriginalL'auteur AAW
Supposons que vous seulement a index entier. si elle est traitée à l'aide de pâte FILO (de la Première À la Dernière) et non pas en référence différents, et seulement à l'aide d'un tableau de données. À l'aide de c'est 6 l'espace sous forme de pile de référence doit permettre:
vous pouvez tout simplement à l'aide de 4 l'espace, parce que la tête-1 = 0 et la dernière-3 = longueur du tableau. Si vous utilisez FIFO (First In First Out), vous devez ré-indexation.
nb: je suis en train de travailler sur l'amélioration de mon anglais.
OriginalL'auteur zainal Abidin
première pile croît à 3n,
deuxième pile augmente à 3n+1,
troisième pousse à 3n+2
pour n={0...N}
Ne pas les exigences d'ajustement. Une fois la première pile a 1/3 autant d'entrées que la longueur du tableau, il déborde, indépendamment de savoir si il y a de l'espace dans le tableau alloué pour les piles 2 et 3.
Il peut perdre 2/3ème de l'espace dans le pire des cas.
OriginalL'auteur Gunjan
Encore une autre approche (en supplément liste liée) est d'utiliser la carte de piles. Dans ce cas, vous allez avoir à utiliser d'autres journaux(3^n)/log(2) bits pour la construction de la carte de distribution des données dans votre n-longueur du tableau. 3-la valeur de la partie de la carte qui dit pile est propriétaire de l'élément suivant.
Ex.
a.push(1); b.push(2); c.push(3); a.push(4); a.push(5);
vous donnera imageapproprié de la valeur de la carte est calculée, bien que des éléments est poussé sur la pile (avec décalage de contenu de tableau)
et la durée des piles 3,1,1
Une fois que vous aurez envie de faire
c.pop()
vous devrez réorganiser vos éléments par trouver de la position réelle dec.top()
dans le tableau d'origine par le biais de la marche dans la cellule de la carte (c'est à dire diviser par 3 alors que les mod par 3 n'est pas 2) puis changer tout le contenu dans le tableau arrière pour couvrir le trou. Tout en marchant à travers la cellule de la carte, vous aurez à stocker toutes les positions que vous avez passé (mapX
) et après le passage de celui qui points à pile "c", vous aurez à diviser par 3 encore une autre fois et de le multiplier par 3^(montant des positions adoptées-1) et ajoutermapX
pour obtenir la nouvelle valeur de cellules-carte.Les frais généraux pour qu'fixe et dépend de la taille de l'élément de la pile (
bits_per_value
):(log(3n)/log(2)) /(nlog(bits_per_value)/log(2)) = log(3n) /(nlog(bits_per_value)) = log(3) /log(bits_per_value)
Donc, pour
bits_per_value = 32
il sera de 31,7% de líespace et avec la croissance de labits_per_value
il sera temps de chute (c'est à dire pour la version 64 bits, il sera de 26,4%).OriginalL'auteur ony
Dans cette approche, toute pile peut croître aussi longtemps qu'il y a une place libre dans le tableau.
Nous séquentiellement allouer de l'espace pour les piles et de nous lier de nouveaux blocs pour le bloc précédent. Cela signifie que tout élément nouveau dans une pile conserve un pointeur vers le haut précédents élément de la pile.
OriginalL'auteur maxpayne
Ce code met en œuvre 3 piles de tableau unique. Il prend soin de vide et remplit les espaces vides entre les données.
OriginalL'auteur Rathish Kannan
Une autre solution en PYTHON, s'il vous plaît laissez-moi savoir si cela fonctionne comme ce que vous en pensez.
OriginalL'auteur James Sapam
Peut-être que vous pouvez mettre en œuvre un nombre N de piles ou de files d'attente dans le seul tableau. Mon defination de l'utilisation de la matrice unique, c'est que nous sommes en utilisant un seul tableau pour stocker toutes les données de toutes les piles et les files d'attente dans le tableau unique, de toute façon, nous pouvons utiliser d'autres N tableau de garder une trace des indices de tous les éléments de particulier pile ou file d'attente.
solution :
stocker des données de manière séquentielle dans le tableau pendant le temps de l'insertion dans un de la pile ou de la file d'attente. et de le stocker de l'indice correspondant à l'indice de maintien de tableau de la pile ou de la file d'attente.
pour exemple : vous avez 3 piles (s1, s2, s3) et que vous souhaitez mettre en œuvre ce à l'aide d'un seul tableau (dataArray[]). Donc, nous allons faire 3 autres tableaux (a1[], a2[], a3[]) pour s1, s2 et s3 respectivement, ce qui permettra de garder une trace de l'ensemble de leurs éléments dans dataArray[] par la sauvegarde de leur indice respectif.
et ainsi de suite ...
maintenant, nous allons effectuer l'opération dans dataArray[] en utilisant a1, a2 et a3 pour les piles et les files d'attente.
pop un élément à partir de s1
retour a1[0]
maj tous les éléments à gauche
faire la même démarche pour d'autres opérations de trop et vous pouvez mettre en œuvre n'importe quel nombre de piles et les files d'attente dans le seul tableau.
OriginalL'auteur Aditya