Как удалить элемент стека, который не находится в верхней части стека в С#
К сожалению, элемент можно удалить только из стека, нажав "pop". Стек не имеет метода "удалить" или что-то подобное, но у меня есть стек (да, мне нужен стек!), Из которого мне нужно удалить некоторые элементы между ними.
Есть ли уловка для этого?
Ответы
Ответ 1
Если вам нужно удалить элементы, которые не находятся сверху, вам нужно что-то другое, кроме стека.
Попробуйте создать собственную реализацию стека из списка. Затем вы можете реализовать свои собственные функции push и pop (добавить и удалить в списке) и собственную специальную функцию PopFromTheMiddle.
Например
public class ItsAlmostAStack<T>
{
private List<T> items = new List<T>();
public void Push(T item)
{
items.Add(item);
}
public T Pop()
{
if (items.Count > 0)
{
T temp = items[items.Count - 1];
items.RemoveAt(items.Count - 1);
return temp;
}
else
return default(T);
}
public void Remove(int itemAtPosition)
{
items.RemoveAt(itemAtPosition);
}
}
Ответ 2
Рассмотрим использование другого контейнера. Может быть, LinkedList.
Затем вы можете использовать
AddFirst
AddLast
RemoveLast
RemoveFirst
просто как pop/push из стека, и вы можете использовать
Remove
чтобы удалить любой node из середины списка
Ответ 3
Возможно, будет работать метод расширения, хотя, я подозреваю, что совершенно необходима всякая структура данных.
public static T Remove<T>( this Stack<T> stack, T element )
{
T obj = stack.Pop();
if (obj.Equals(element))
{
return obj;
}
else
{
T toReturn = stack.Remove( element );
stack.Push(obj);
return toReturn;
}
}
Ответ 4
В истинном стеке это можно сделать только одним способом -
Поместите все элементы до тех пор, пока вы не удалите тот, который вы хотите, затем нажмите их обратно в стек в соответствующем порядке.
Это не очень эффективно.
Если вы действительно хотите удалить из любого места, я бы рекомендовал создать псевдо-стек из списка, LinkedList или какой-либо другой коллекции. Это даст вам контроль, чтобы сделать это легко.
Ответ 5
Вы можете использовать LinkedList
Удаление списков, вероятно, будет менее эффективным.
При удалении по ссылке Стыки, основанные на списках, будут иметь O (N) поиск и O (N) изменение размера. Поиск LinkedList - это O (N), а удаление - O (1).
Для удаления по индексу LinkedList должен иметь обход O (N) и O (1), тогда как List имеет обход O (1) (потому что это индексирование) и O (N) удаление из-за изменения размера.
Помимо эффективности, реализация LinkedList будет держать вас в стандартной библиотеке, открывая ваш код для большей гибкости и вы пишете меньше.
Это должно быть способно обрабатывать Pop, Push и Remove
public class FIFOStack<T> : LinkedList<T>
{
public T Pop()
{
T first = First();
RemoveFirst();
return first;
}
public void Push(T object)
{
AddFirst(object);
}
//Remove(T object) implemented in LinkedList
}
Ответ 6
Тогда это не стежок? Стек LAST in FIRST out
.
Вам придется написать пользовательский или выбрать что-то еще.
Ответ 7
Stack temp = new Stack();
object x, y;
While ((x = myStack.Pop()) != ObjectImSearchingFor)
temp.Push(x);
object found = x;
While ((y = temp.Pop()) != null)
myStack.Push(y);
Ответ 8
Конструктор Stack < > принимает IEnumerable < > в качестве параметра. Таким образом, можно было бы выполнить следующее:
myStack = new Stack<item>( myStack.Where(i => i != objectToRemove).Reverse() );
Это не работает по-разному.
Ответ 9
Трюк, который я использую в волосатых ситуациях, добавляет флаг "устаревший" к элементам в стеке.
Когда я хочу "удалить" элемент, я просто поднимаю этот флаг (и очищаю все ресурсы, которые предпринимает объект).
Затем, когда элементы Pop() меня просто проверяют, поднят ли флаг, и снова появятся в цикле до тех пор, пока не будет найден не-устаревший элемент.
do
{
obj = mQueue.Pop();
} while (obj.deprecated);
Вы можете управлять своим собственным количеством элементов, чтобы узнать, сколько "реальных" элементов все еще находится в очереди, и, очевидно, блокировка должна использоваться, если это необходимо для многопоточного решения.
Я обнаружил, что для очередей, которые имеют постоянный поток через них - предметы толкаются и выскакивают - гораздо эффективнее его обманывать, тем быстрее вы можете получить (заплатив O (1) за удаление элемента из середины) и память разумна, если сохраняемый объект мал, это в основном не имеет значения, если предметы текут в разумном темпе.
Ответ 10
hmmmm...... Я согласен с предыдущими двумя ответами, но если вы хотите взломать свой путь, просто нажмите и сохраните все элементы, пока не дойдете до того, который вы хотите, и повторно нажмите их все
Да, это уродливый, плохо исполняемый, вероятно, странный код, которому потребуется длинный комментарий, объясняющий почему, но вы могли бы это сделать....