如何在Java中查找队列中元素的最后一次出现

时间:2018-07-01 19:41:06

标签: java

我正在尝试查找特定字符串中最后一次出现的字符串 我正在使用另一个队列和变量。我被困在这里,我应该使用堆栈还是队列来解决这个问题以及如何解决。 任何帮助将不胜感激。

import java.util.Stack;
import java.util.Queue;
import java.util.LinkedList;

public class StackQueue{
public static void remove(Queue<String> queue, String toRemove){
    if(queue.isEmpty()){throw new NullPointerException();}

    Queue<String> tmp = new LinkedList<>();
    Queue<String> tmp1 = new LinkedList<>();
    int count = 0;

    while(! queue.isEmpty()){
        String removed = queue.remove();        
        if(toRemove == removed){
            tmp.add(removed);
            count++;
        }
        else{
            tmp1.add(removed);
        }       
    }

    while (!tmp1.isEmpty()){
        queue.add(tmp1.remove());
    }
}
public static void main(String[] args){
    Queue<String> q = new LinkedList<>();
    q.add("a");
    q.add("e");
    q.add("b");
    q.add("a");     
    q.add("e");


    System.out.println(q);
    remove(q, "a");     
    System.out.println(q);
}
 }

4 个答案:

答案 0 :(得分:2)

Queue不太适合您的用法,实际上,类StackQueue的名称暗示您可能想要Deque(尽管这可能是巧合)。

Deque(双端队列)接口指定了您需要的确切方法removeLastOccurrence(Object o)。本质上,Deque允许您从两端添加删除,这也有助于Stack的行为,因此,如果更加灵活,则可以从两端执行删除操作。

相反,Queue仅提供从队列的开头或通过搜索在Queue中发现的首次出现(尽管这可能取决于实现,因为指定了remove(Object o)方法) Collection界面中的状态未声明它必须是第一次出现...)

在您的用例中,Queue的问题在于该接口旨在仅允许类似队列的行为,从而防止在不强制转换的情况下使用底层实现,这将使此类任务更容易执行(例如LinkedListArrayDeque)。为此,强制转换很遥不可及,如果实际实现发生了变化,该怎么办?

如果您坚持使用Queue,则不需要制作另一个Queue的另一个解决方案将是使用队列的IteratorIterator.remove()。例如:

import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;

public class QueueExample {

    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();
        queue.add("a");
        queue.add("b");
        queue.add("c");
        queue.add("a");
        queue.add("d");
        queue.add("a");
        queue.add("b");
        System.out.println("Before: " + queue);
        remove(queue, "a");
        System.out.println("After: " + queue);
    }

    public static void remove(Queue<String> queue, String toRemove){
        int indexToRemove = findLastIndex(queue, toRemove);
        removeIndex(queue, indexToRemove);
    }

    private static int findLastIndex(Queue<String> queue, String value) {
        int indexToRemove = -1;
        int index = 0;
        for (Iterator<String> iterator = queue.iterator(); iterator.hasNext(); index++) {
            String current = iterator.next();
            if (value.equals(current)) {
                indexToRemove = index;
            }
        }
        return indexToRemove;
    }

    private static void removeIndex(Queue<String> queue, int indexToRemove) {
        int index = 0;
        for (Iterator<String> iterator = queue.iterator(); iterator.hasNext() && index <= indexToRemove; index++) {
            iterator.next();
            if (index == indexToRemove) {
                iterator.remove();
            }
        }
    }
}

答案 1 :(得分:1)

这是一种方法。遍历队列并将其内容转储到临时队列中(就像您正在做的那样)。跟踪要删除的元素的最后一次看到的索引。最后,遍历临时队列并将其内容转储回原始队列,而忽略找到索引处的项目。

.blur {
    -webkit-filter: blur(125px);
    -moz-filter: blur(125px);
    -o-filter: blur(125px);
    -ms-filter: blur(125px);
    filter: blur(125px);
}

答案 2 :(得分:0)

完全不同意d.j.brown,堆栈最适合您的情况。实际上,有一个内置函数可以返回lastIndexOf堆栈中的一个元素。下面是工作示例。

public static void main(String[] args) {
    Stack<String> stack = new Stack<>();
    stack.add("a");
    stack.add("e");
    stack.add("b");
    stack.add("k");
    stack.add("b");
    stack.add("c");
    stack.add("l");

    System.out.println("Original stack: " + stack);
    remove(stack, "a");
    System.out.println("Modified stack: " + stack);
  }

  private static void remove(Stack<String> stack, String toRemove) {
    int indexOfToRemove = stack.lastIndexOf(toRemove);
    if (indexOfToRemove == -1) {
      return;
    }
    Stack<String> tempStack = new Stack<>();
    int originalSize = stack.size();
    for (int i = 0; i < originalSize - indexOfToRemove - 1; i++) {
      tempStack.push(stack.pop());
    }
    stack.pop();  //Extra pop to remove the desired element
    System.out.println("Temporary stack: " + tempStack);
    while (!tempStack.empty()) {
      stack.push(tempStack.pop());
    }
  }

输出:

Original stack: [a, e, b, k, b, c, l]
Temporary stack: [l, c, b, k, b, e]
Modified stack: [e, b, k, b, c, l]

答案 3 :(得分:0)

使用双端队列。您可以在两侧添加/删除。 deque.getLast(),deque.getFirst()会为您提供所需的内容。