К сожалению, элемент можно удалить только из стека, нажав "pop". Стек не имеет метода "удалить" или что-то подобное, но у меня есть стек (да, мне нужен стек!), Из которого мне нужно удалить некоторые элементы между ними.
Есть ли уловка для этого?
К сожалению, элемент можно удалить только из стека, нажав "pop". Стек не имеет метода "удалить" или что-то подобное, но у меня есть стек (да, мне нужен стек!), Из которого мне нужно удалить некоторые элементы между ними.
Есть ли уловка для этого?
Если вам нужно удалить элементы, которые не находятся сверху, вам нужно что-то другое, кроме стека.
Попробуйте создать собственную реализацию стека из списка. Затем вы можете реализовать свои собственные функции 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);
}
}
Рассмотрим использование другого контейнера. Может быть, LinkedList. Затем вы можете использовать
AddFirst AddLast RemoveLast RemoveFirst
просто как pop/push из стека, и вы можете использовать
Remove
чтобы удалить любой node из середины списка
Возможно, будет работать метод расширения, хотя, я подозреваю, что совершенно необходима всякая структура данных.
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;
}
}
В истинном стеке это можно сделать только одним способом -
Поместите все элементы до тех пор, пока вы не удалите тот, который вы хотите, затем нажмите их обратно в стек в соответствующем порядке.
Это не очень эффективно.
Если вы действительно хотите удалить из любого места, я бы рекомендовал создать псевдо-стек из списка, LinkedList или какой-либо другой коллекции. Это даст вам контроль, чтобы сделать это легко.
Вы можете использовать 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
}
Тогда это не стежок? Стек LAST in FIRST out
.
Вам придется написать пользовательский или выбрать что-то еще.
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);
Конструктор Stack < > принимает IEnumerable < > в качестве параметра. Таким образом, можно было бы выполнить следующее:
myStack = new Stack<item>( myStack.Where(i => i != objectToRemove).Reverse() );
Это не работает по-разному.
Трюк, который я использую в волосатых ситуациях, добавляет флаг "устаревший" к элементам в стеке. Когда я хочу "удалить" элемент, я просто поднимаю этот флаг (и очищаю все ресурсы, которые предпринимает объект). Затем, когда элементы Pop() меня просто проверяют, поднят ли флаг, и снова появятся в цикле до тех пор, пока не будет найден не-устаревший элемент.
do
{
obj = mQueue.Pop();
} while (obj.deprecated);
Вы можете управлять своим собственным количеством элементов, чтобы узнать, сколько "реальных" элементов все еще находится в очереди, и, очевидно, блокировка должна использоваться, если это необходимо для многопоточного решения.
Я обнаружил, что для очередей, которые имеют постоянный поток через них - предметы толкаются и выскакивают - гораздо эффективнее его обманывать, тем быстрее вы можете получить (заплатив O (1) за удаление элемента из середины) и память разумна, если сохраняемый объект мал, это в основном не имеет значения, если предметы текут в разумном темпе.
hmmmm...... Я согласен с предыдущими двумя ответами, но если вы хотите взломать свой путь, просто нажмите и сохраните все элементы, пока не дойдете до того, который вы хотите, и повторно нажмите их все
Да, это уродливый, плохо исполняемый, вероятно, странный код, которому потребуется длинный комментарий, объясняющий почему, но вы могли бы это сделать....