截断Java堆栈

时间:2015-04-02 18:59:44

标签: java

我在Java中定义了Stack<String>,用于在工作流程中导航。

我想要做的是确保堆栈中的所有值都是唯一的:当转换到“previous”状态时,我希望在堆栈中第一次出现先前状态后删除堆栈中的所有内容

有一种简单的方法吗?

编辑:请求了更多信息。以下是堆栈内容的示例:

[state2, state3, state2, state1, startState]

我需要能够接受一个String,检查堆栈并查看它是否有多次出现,然后弹出元素直到该String的“最底部”出现。 “截断”可能是对我想要做的一个不好的描述......“直到我点击一个任意索引”才可能更接近我需要的东西。

4 个答案:

答案 0 :(得分:1)

考虑使用deque。下面的链接解释了为什么要在堆栈上使用它。

Why should I use Deque over Stack?

答案 1 :(得分:1)

Stack实现List(在其他各种接口中)。获取最后一个元素的ListIterator,然后向后移动它,直到找到新状态的出现,计算沿途的元素数量,然后弹出那么多元素。 (如果你没有找到新状态,那么当然你不会弹出任何东西,而是将新状态推到堆栈上。)

这可能效率不高,但肯定会有效。如果您还希望它有效,您可能需要使用另一种数据结构(代替堆栈或代替堆栈)。一种可能性是使用Map(除了堆栈)来跟踪堆栈中的哪些状态以及它们发生的索引,或至少Set来跟踪哪些状态在堆栈中(然后您可以弹出状态,直到找到您要查找的状态)。您将维护堆栈和地图或并行设置。

或者如果你认真对待:

  

&#34;弹出,直到我击中任意索引&#34;可能更接近我的需要。

......那肯定就足够了:

int numberToPop = stack.size() - arbitraryIndex - 1;
while (numberToPop-- > 0) {
    stack.pop();
}

答案 2 :(得分:0)

如果你创建了一个基本上是一个堆栈的自己的容器,它会简化你的整体代码吗?像(不是完整的实现):

public class StackSet<T> {
    private final Set<T> set;
    private final Deque<T> queue;

    public StackSet(){
        set = new HashSet<>();
        queue = new ArrayDeque<>();
    }

    public void push(T value){
        if(set.add(value)){
            queue.push(value);
        }
    }

    public T pop(){
        return queue.pop();
    }
}

这应该保证没有重复。

答案 3 :(得分:0)

这是一个使用Deque而不是Stack的truncate方法的示例。

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Collection;
import java.util.Deque;

public class ExampleDeque 
{

  public static void main(String[] args)    
  {
    Deque<String> deque = new ArrayDeque<String>();
    deque.offer("startState");
    deque.offer("state1");
    deque.offer("state2");
    deque.offer("state3");
    deque.offer("state2");

    System.out.println("Before");
    print(deque);
    deque = truncate(deque, "state2");
    System.out.println("After");
    print(deque);
  }

  static Deque<String> truncate (Deque<String> deque, String value)
  {
    if(!deque.contains(value)) return deque;

    String[] array = deque.toArray(new String[deque.size()]);
    for(int i = 0; i < array.length;  i++)
    {
      if(array[i] == value)
      {
        String[] truncated = Arrays.copyOfRange(array, 0, i + 1);
        Collection<String> collection = Arrays.asList(truncated);   
        return new ArrayDeque<>(collection);
      }
    }
    return null;
  }

  static void print(Deque<String> deque)
  {
    for(String s : deque)
      System.out.println(s);
    System.out.println();
  }
}