Java 实现一个队列,在该队列中,您可以在固定时间内排队/退队时在特定位置插入元素?

Java 实现一个队列,在该队列中,您可以在固定时间内排队/退队时在特定位置插入元素?,java,algorithm,data-structures,queue,Java,Algorithm,Data Structures,Queue,样本输入: 2 3 101 102 103 3 201 202 203 ENQUEUE 101 ENQUEUE 201 ENQUEUE 102 ENQUEUE 202 ENQUEUE 103 ENQUEUE 203 DEQUEUE DEQUEUE DEQUEUE DEQUEUE DEQUEUE DEQUEUE STOP 第一行=组数,N 以下N行=第一个数字是K组中元素的#,以下K个数字是元素本身(范围为0…999999) 停止输入之前的所有行=排队或出列查询。如果排队,则您正在将当前正在处理

样本输入:

2
3 101 102 103
3 201 202 203
ENQUEUE 101
ENQUEUE 201
ENQUEUE 102
ENQUEUE 202
ENQUEUE 103
ENQUEUE 203
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
DEQUEUE
STOP
第一行=组数,N

以下N行=第一个数字是K组中元素的#,以下K个数字是元素本身(范围为0…999999)

停止输入之前的所有行=排队或出列查询。如果排队,则您正在将当前正在处理的元素E排队,在A处。如果队列中没有与E或B属于同一“组”的元素,则在队列的末尾。位于与E属于同一“组”的最后一个元素的正后方

出列很简单,只需从队列中删除第一个元素。对于每个出列查询,输出出列的元素

一个元素的排队和出列只应花费恒定时间

产出将是:

101
102
103
201
202
203
我最初考虑的是某种2D嵌套结构,比如队列数组之类的,但排队/退队不会花费固定的时间,所以我不确定

另外,我在查询之前得到了元素本身这一事实应该是一个提示,但我不确定这一点。

如果组不相交,则来自每个组的元素总是聚集在一起。换句话说,您有一个队列:

  • 对于每个组,创建一个(初始为空)队列
  • 创建索引结构,用于与输入的编号相对应的组的恒定时间搜索(暴力解决方案是一个具有1000000个引用的数组,可以更改为HashSet)
  • 创建队列引用队列(“主”队列)
现在为
排队X

  • 查找
    X
    对应的队列
  • 添加
    X
    ;如果该队列为空,请将该队列排入主队列
对于
出列

  • 取主队列中的第一个队列,从中取出元素
  • 如果为空,则从主队列中退出队列

    • 假设: 1.一个元素只属于一个组。 2.排队查询将包含在一个组中有条目的数据

      代码:

      public class Queue {
          private static final BufferedReader BR = new BufferedReader(new InputStreamReader(System.in));
          private static int noOfGroups = 0;
          private static int totalNumberOfElements = 0;
          private static HashMap<String, Element> elementsMap = new HashMap<String, Element>();
          private static HashMap<Integer, Group> groupsMap = new HashMap<Integer, Group>();
          private static Element queueStart = null;
          private static Element queueEnd = null;
      
          public static void main(String[] args) throws IOException {
              StringBuffer output = new StringBuffer();
              getInput(InputType.NO_OF_GROUP, null);
              for (int groupId = 0; groupId < noOfGroups; ++groupId) {
                  getInput(InputType.GROUP_ENTRY, groupId);
              }
              if (elementsMap.size() != totalNumberOfElements) {
                  System.err.println(
                          "Note: Same element found on different groups. Group that entered later will be considered.");
              }
              String query;
              while (!"STOP".equals(query = getInput(InputType.QUERY_ENTRY, null))) {
                  if (query.equals("DEQUEUE")) {
                      Element element = processDEQUEUE();
                      if (element != null) {
                          // output the element that is dequeued.
                          output.append(element.getData()).append(System.lineSeparator());
                      }
                  } else {
                      processENQUEUE(query);
                  }
              }
              System.out.println(System.lineSeparator() + "Result:");
              System.out.println(output);
      
          }
      
          private static void processENQUEUE(String data) {
              Element currentElement = elementsMap.get(data);
              if (currentElement != null) {
      
                  int groupId = currentElement.getGroupId();
                  Group currentGroup = groupsMap.get(groupId);
      
                  if (currentGroup.getLast() == null) {
                      // Case A:
                      // queuing the element "data" at the end of the queue if there's no
                      // element in the queue that belongs to the same "group" as "data"
                      currentGroup.setLast(currentElement);
                      if (queueStart == null) {
                          queueStart = currentElement;
                      }
                      if (queueEnd == null) {
                          queueEnd = currentElement;
                      } else {
                          queueEnd.setNext(currentElement);
                          queueEnd = currentElement;
      
                      }
      
                  } else if (currentGroup.getLast() != null) {
                      // Case B:
                      // queuing the element "data" right behind the last element which
                      // belongs to the same "group" as "data"
                      currentElement.setNext(currentGroup.getLast().getNext());
                      currentGroup.getLast().setNext(currentElement);
                      currentGroup.setLast(currentElement);
      
                  }
      
              } else {
                  System.err.println("Cannot process enqueue for " + data + ". There is no group that contains this data.");
              }
      
          }
      
          private static Element processDEQUEUE() {
              Element element = null;
              // removing the first element from the queue.
              if (queueStart == null) {
                  System.err.println("Cannot process dequeue. Queue is empty.");
              } else {
                  element = queueStart;
                  queueStart = queueStart.getNext();
              }
              return element;
          }
      
          private static String getInput(InputType inputType, Integer groupId) throws IOException {
              boolean isValidInput = false;
              String input = null;
              String message = null;
              String returnValue = null;
              while (!isValidInput) {
                  switch (inputType) {
                  case NO_OF_GROUP:
                      System.out.println("Number of \"groups\": ");
                      break;
                  case GROUP_ENTRY:
                      System.out.println("Group-" + groupId + " Entry: ");
                      break;
                  case QUERY_ENTRY:
                      System.out.println("Query: ");
                  }
                  input = BR.readLine();
                  switch (inputType) {
                  case NO_OF_GROUP:
                      try {
                          noOfGroups = Integer.parseInt(input);
                          isValidInput = true;
                      } catch (NumberFormatException ex) {
                          message = ex.getMessage();
                          isValidInput = false;
                      }
                      break;
                  case GROUP_ENTRY:
                      try {
                          String groupInputElements[] = input.split(" ");
                          int noOfElements = 0;
      
                          noOfElements = Integer.parseInt(groupInputElements[0]);
                          if (groupInputElements.length != noOfElements + 1) {
                              throw new IllegalArgumentException("Expecting " + noOfElements + " elements. Found "
                                      + (groupInputElements.length - 1) + " elements.");
                          }
                          groupsMap.put(groupId, new Group());
                          for (int index = 1; index < groupInputElements.length; ++index) {
                              Element element = new Element();
                              element.setGroupId(groupId);
                              element.setData(groupInputElements[index]);
                              elementsMap.put(groupInputElements[index], element);
                          }
                          totalNumberOfElements += noOfElements;
                          isValidInput = true;
                      } catch (IllegalArgumentException ex) {
                          message = ex.getMessage();
                          isValidInput = false;
                      }
                      break;
                  case QUERY_ENTRY:
                      try {
                          if (!input.contains("ENQUEUE") && !input.equals("DEQUEUE") && !input.equals("STOP")) {
                              throw new IllegalArgumentException("Query can only be ENQUEUE, DEQUEUE or STOP");
                          } else if (input.contains("ENQUEUE")) {
                              String[] enqueueData = input.split(" ");
                              if (enqueueData.length != 2) {
                                  throw new IllegalArgumentException(
                                          "Invalid Data. Expected format: ENQUEUE <DATA>\t\tExample: ENQUEUE 101");
                              }
                              returnValue = enqueueData[1];
                          } else {
                              returnValue = input;
                          }
                          isValidInput = true;
                      } catch (IllegalArgumentException ex) {
                          message = ex.getMessage();
                          isValidInput = false;
                      }
                  }
                  if (message != null) {
                      System.err.println(message);
                      message = null;
                  }
      
              }
              return returnValue;
          }
      
      }
      
      enum InputType {
          NO_OF_GROUP, GROUP_ENTRY, QUERY_ENTRY
      }
      
      class Element {
          private Element next;
          private int groupId;
          private String data;
      
          public Element getNext() {
              return next;
          }
      
          public void setNext(Element next) {
              this.next = next;
          }
      
          public int getGroupId() {
              return groupId;
          }
      
          public void setGroupId(int groupId) {
              this.groupId = groupId;
          }
      
          public String getData() {
              return data;
          }
      
          public void setData(String data) {
              this.data = data;
          }
      }
      
      class Group {
      
          public Element getLast() {
              return last;
          }
      
          public void setLast(Element last) {
              this.last = last;
          }
      
          private Element last;
      }
      
      公共类队列{
      私有静态最终BufferedReader BR=新BufferedReader(新InputStreamReader(System.in));
      私有静态int noOfGroups=0;
      私有静态int totalNumberOfElements=0;
      private static HashMap elementsMap=new HashMap();
      私有静态HashMap groupsMap=newhashmap();
      私有静态元素queueStart=null;
      私有静态元素queueEnd=null;
      公共静态void main(字符串[]args)引发IOException{
      StringBuffer输出=新的StringBuffer();
      getInput(InputType.NO\u属于\u组,为空);
      对于(int-groupId=0;groupId