简体   繁体   English

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

[英]How to find the last Occurence of an element in a Queue in Java

I am trying to find the last occurence of a particular string in a queue.I am using another queues and variables.我试图在队列中找到特定字符串的最后一次出现。我正在使用另一个队列和变量。 I am stuck here though, should i use stacks or queues to solve this and how.我被困在这里,我应该使用堆栈还是队列来解决这个问题以及如何解决。 Any help would be appreciated.任何帮助,将不胜感激。

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);
}
 }

A Queue isn't a good fit for your usage, in fact the name of your class StackQueue hints that you probably want a Deque (although this may be coincidence). Queue不适合您的使用,实际上您的类StackQueue的名称暗示您可能想要一个Deque (尽管这可能是巧合)。

The Deque (double-ended queue) interface specifies the exact method you require, removeLastOccurrence(Object o) . Deque (双端队列)接口指定了您需要的确切方法removeLastOccurrence(Object o) Essentially a Deque lets you add a remove from both ends, which also facilitates Stack behavior and so if a lot more flexible, giving you remove operations which work from both ends.从本质上讲, Deque允许您从两端添加删除,这也有助于Stack行为,因此如果更加灵活,则可以为您提供在两端都有效的删除操作。

A Queue in contrast only provides removal from the front of the queue or by searching for first occurrence found in the Queue (although this can be implementation dependent since the remove(Object o) method specified in the Collection interface does not state that it has to be the first occurrence...)Queue相反只提供了从队列的前部或通过搜索第一次出现去除在所找到的Queue (尽管这可以是依赖于实现的,因为remove(Object o)中所指定的方法Collection接口不状态,它有至是第一次出现...)

The issue with a Queue for your use case is that the interface is intended to only allow queue like behavior, preventing usage of the underlying implementation without casting which would allow such a task to be performed more easily (eg LinkedList or ArrayDeque ).对于您的用例, Queue的问题是该接口旨在仅允许类似队列的行为,防止使用底层实现而不进行强制转换,这将允许更轻松地执行此类任务(例如LinkedListArrayDeque )。 Casting is far from desirable for this, what if the actual implementation changed?铸造远非可取的,如果实际的实现改变了怎么办?

If you insist on using a Queue then another solution which does not requiring making another Queue would be to use the queue's Iterator and Iterator.remove() .如果您坚持使用Queue那么另一种不需要创建另一个Queue解决方案是使用队列的IteratorIterator.remove() For example:例如:

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();
            }
        }
    }
}

Here's one way to do it.这是一种方法。 Iterate through the queue and dump its contents into a temporary queue (like you're doing).遍历队列并将其内容转储到临时队列中(就像您正在做的那样)。 Keep track of the last seen index of the element to remove.跟踪要删除的元素的最后看到的索引。 Lastly, iterate through the temporary queue and dump its contents back into the original queue, ignoring the item at the found index.最后,遍历临时队列并将其内容转储回原始队列,忽略找到的索引处的项目。

public static void remove(Queue<String> queue, String toRemove) {
    Queue<String> tmp = new LinkedList<>();
    int lastFoundIdx = -1;

    for (int i = 0; !queue.isEmpty(); i++) {
        String elem = queue.poll();

        if (elem.equals(toRemove)) {
            lastFoundIdx = i;
        }

        tmp.offer(elem);
    }

    for (int i = 0; !tmp.isEmpty(); i++) {
        if (i == lastFoundIdx) {
            tmp.poll();
        }
        else {
            queue.offer(tmp.poll());
        }
    }
}

Could not agree more to djbrown, stack is the best fit for your case.不能更同意 djbrown,stack 最适合您的情况。 In fact there is a built in function that returns lastIndexOf an element of a stack.事实上,有一个内置函数返回 lastIndexOf 堆栈的一个元素。 Below is the working example.下面是工作示例。

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());
    }
  }

Output:输出:

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]

Use Deque.使用双端。 You can add/remove on both sides.您可以在两侧添加/删除。 deque.getLast(), deque.getFirst() will give you that what you want. deque.getLast(), deque.getFirst() 会给你你想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java:如何查找部分初始化的排序数组的最后一个元素的索引 - Java: How to find index of last element of partially initialized sorted array 如何在Java的mongodb中使用聚合来多次查找字段? - How to use aggregation in mongodb with Java to find occurence of a field multiple times? Java最后一次出现的正则表达式,直到字符串结尾 - Java last occurence of regex till end of string 使用 java 中的流在 Integer ArrayList 中查找元素第二次出现的索引 - Find the index of 2nd occurence of an element in an Integer ArrayList using streams in java 如何从java中的队列中删除特定元素(不是优先级队列) - how to remove a specific element from queue in java(not priority queue) 如何在Java中的Queue前面添加元素? - How to add an element in front of Queue in java? 如何在Java中找到远程MQ队列的本地传输队列? - How to find local transmission queue of remote MQ queue in Java? 在java中找到字符串中子串的第n个出现位置? - find the nth occurence of a substring in a string in java? Java-我如何依次查找可能未填充的数组中元素的最后出现? - Java-How do I sequentially find the last occurrence of an element in an array that may not be filled? 如何找到最后的“ href” <tr> 元件? - How to find the “href” of the last <tr> element?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM