Как определить размер, сначала STACK в java и удалить данные между STACK

У меня есть 3 книги от "А" до "С". Как отобразить их с помощью Stack, а затем отобразить его размер. Также как я могу удалить книгу "B", а затем снова увидеть размер?

Это мой код:

import java.util.*;
public class test_stack {
 public static void main (String[] args){
 Stack<string> stack = new Stack<string>();
 stack.push("a");
 printStack(stack);
 stack.push("b");
 printStack(stack);
 stack.push("c");
 printStack(stack);
 stack.pop();
 printStack(stack);
 stack.pop();
 printStack(stack);
 stack.pop();
 printStack(stack);
 }
 private static void printStack(Stack<string> s){
 if(s.isEmpty())
 System.out.printIn("empty stack");
 else
 System.out.printf("% s TOP\n", s);
 }
}
</string></string></string>

Выход, который я получаю:

[a] TOP
[a, b] TOP
[a, b, c] TOP
[a, b] TOP
[a] TOP
empty stack

Я хочу достичь:

[a,b,c] TOP
[a,c] TOP
empty stack
6 ответов

Хотя я бы рекомендовал вам использовать другую структуру данных, такую ​​как linked list, если вы хотите удалить из середины, потому что для этого есть linked lists. Вы НЕ должны использовать ВСЕ стеки, если требуется удалить элемент из середины. Но поскольку вопрос задает вопрос, тогда вы можете ввести метод deleteFrom(), как показано ниже.

Этот метод будет принимать два аргумента: стек и объект, подлежащий удалению, и если этот объект присутствует в стеке, он будет удален.

Выход

[a] TOP
[a, b] TOP
[a, b, c] TOP
After calling deleteFrom(stack, "b")
[a, c] TOP

Код метода deleteFrom():

public static Stack<string> deleteFrom(Stack<string> stack, String obj) {
 if (stack.search(obj) == -1) {
 System.out.println("Element doesn't exists in stack.");
 return stack;
 }
 Stack<string> stack2 = new Stack<string>();
 while (stack.search(obj) != -1)
 stack2.push(stack.pop());
 stack2.pop();
 while (stack2.size() != 0)
 stack.push(stack2.pop());
 return stack;
}
</string></string></string></string>

Последний код будет выглядеть так:

import java.util.*;
public class HelloWorld {
 public static void main(String[] args) {
 Stack<string> stack = new Stack<string>();
 stack.push("a");
 printStack(stack);
 stack.push("b");
 printStack(stack);
 stack.push("c");
 printStack(stack);
 stack = deleteFrom(stack, "b");
 System.out.println("After calling deleteFrom(stack, \"b\")");
 printStack(stack);
 }
 private static void printStack(Stack<string> s) {
 if (s.isEmpty()) {
 System.out.println("empty stack");
 } else {
 System.out.printf("%s TOP\n", s);
 }
 }
 public static Stack<string> deleteFrom(Stack<string> stack, String obj) {
 if (stack.search(obj) == -1) {
 System.out.println("Element doesn't exists in stack.");
 return stack;
 }
 Stack<string> stack2 = new Stack<string>();
 while (stack.search(obj) != -1)
 stack2.push(stack.pop());
 stack2.pop();
 while (stack2.size() != 0)
 stack.push(stack2.pop());
 return stack;
 }
}
</string></string></string></string></string></string></string>


Это невозможно сделать с помощью Stack, поскольку это нарушает всю концепцию операций Stack. Даже если мы придумаем функцию, которая удалит элемент из середины стека, а затем за кулисами, он будет удалять все вышеперечисленные элементы > удалить требуемый элемент > снова отбросить вышеуказанные элементы. И определенно это не очень хороший подход.

Концепция использования стека различна. Но если у вас есть сценарий, в котором вы должны удалить элемент из середины, вы должны использовать LinkedList вместо Stack. Это то, что LinkedList в основном для.

package com.tutorialspoint;
import java.util.*;
public class LinkedListDemo {
 public static void main(String[] args) {
 // create a LinkedList
 LinkedList list = new LinkedList();
 // add some elements
 list.add("A");
 list.add("B");
 list.add("C");
 // print the list
 System.out.println("LinkedList:" + list);
 System.out.println("size:" + list.size());
 // remove "B" Element from the list
 list.remove("B");
 // print the list
 System.out.println("LinkedList:" + list);
 System.out.println("size:" + list.size());
 }
}

Выход

LinkedList:[A, B, C]
size: 3
LinkedList:[A, C]
size: 2


Вот реализация Stack с использованием LinkedList с использованием шаблона дизайна адаптера, вам нужно как нажать/поп в любой голове или хвосте, чтобы получить Stack

public class StackLL<e> {
 private LinkedList<e> list;
 public StackLL() {
 list = new LinkedList<>();
 }
 public void push(E e) {
 list.addFirst(e);
 }
 public E pop(E e) {
 Iterator<e> it = list.descendingIterator(); // list.iterator()
 while (it.hasNext()) {
 E ele = it.next();
 if (ele == e) {
 it.remove();
 break;
 }
 }
 return null;
 }
 public E pop() {
 return list.removeFirst();
 }
 public int size() {
 return list.size();
 }
 public void print() {
 System.out.println(list);
 }
}
</e></e></e>

В этой реализации базовая структура данных по-прежнему представляет собой двойной связанный список, поэтому вы можете использовать свои специальные методы для выполнения некоторых специальных операций, в вашем случае это поиск и удаление элемента, поэтому я перегрузил метод pop с помощью элемент, который должен быть удален, он выполняет итерацию и удаляет соответствующий один элемент else, возвращает null.

public static void main(String[] args) {
 StackLL<string> stack = new StackLL<>();
 stack.push("a");
 stack.push("b");
 stack.push("c");
 stack.print();
 stack.pop("b");
 stack.print();
 stack.pop("b");
}
</string>

Выход

[c, b, a]
[c, a]

Если вы хотите удалить элемент mid, вы можете просто иметь элемент в качестве переменной-члена, после каждых 2 нажатий вы можете увеличить его на одну позицию вверх и после каждых двух выходов вы можете уменьшить одну позицию вниз с помощью только O (1 ) сложность.


Чтобы удалить b из вашего стека, вам нужно будет вытащить все книги из стека и вытолкнуть их во временный стек, пока не дойдете до b, а затем вытащите все книги из временного стека и нажмите их обратно в основной стек.

Например:

import java.util.*;
public class test_stack {
 public static void main (String[] args){
 // put a, b and c on the stack
 Stack<string> stack = new Stack<string>();
 stack.push("a");
 stack.push("b");
 stack.push("c");
 printStack(stack);
 // pop items off the stack until we reach b (and push non b items onto temporary stack)
 Stack<string> temporaryStack = new Stack<string>();
 String currentItem;
 do {
 currentItem = stack.pop();
 if(!currentItem.equals("b")) {
 temporaryStack.push(currentItem);
 } while(!currentItem.equals("b"));
 // push temporary stack back onto main stack
 while(!temporaryStack.isEmpty()) {
 stack.push(temporaryStack.pop());
 }
 printStack(stack);
 }
 private static void printStack(Stack<string> s){
 if(s.isEmpty())
 System.out.printIn("empty stack");
 else
 System.out.printf("% s TOP\n", s);
 }
}
</string></string></string></string></string>


Я не думаю, что это можно сделать с помощью общих операций стека push и pop. Помните, что стек - LIFO. Поэтому, чтобы удалить (POP) b, вам нужно удалить (POP) c. И снова вам нужно нажать c.

Изменить: если вам удастся выполнить требуемую цель, будьте уверены, что вы не использовали концепцию стеков. Счастливое кодирование!!:)


Вы можете создать второй временный стек для хранения значений над элементом, который вы хотите удалить:

Stack<string> stack = new Stack<string>();
stack.push("a");
stack.push("b");
stack.push("c");
// Pop the elements from the original stack onto
// the temporary stack.
Stack<string> temp = new Stack<string>();
while (!stack.isEmpty()) {
 String top = stack.pop();
 if (top.equals("b")) {
 break;
 }
 temp.push(top);
}
// Pop the elements from the temporary stack
// back into the original stack. This preserves
// the original order.
while (!temp.isEmpty()) {
 stack.push(temp.pop());
}
</string></string></string></string>

licensed under cc by-sa 3.0 with attribution.