[英]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
的问题是该接口旨在仅允许类似队列的行为,防止使用底层实现而不进行强制转换,这将允许更轻松地执行此类任务(例如LinkedList
或ArrayDeque
)。 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
解决方案是使用队列的Iterator
和Iterator.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.