点击打开链接
GET PUT msg1 10 5 PUT msg2 10 4 GET GET GET
EMPTY QUEUE! msg2 10 msg1 10 EMPTY QUEUE!
根据操作指令进行操作,也就是出队,还是入队。而在出队时,要注意,保证优先级低的先出来,要是优先级一样的话,就先入队的先出来。从题目就很容易看出要用优先队列做,恰好java包中有个PriorityQueue类,就是现成的优先队列。
解题过程:首先根据题意,可以建一个Message类,这里面包括mesg的一些信息,主要包括,优先级和进队的序列号(这个序列号必须要,也就是第几个进队的,后面就知道了)。然后根据指令一步一步的操作,就可以得到答案。
1、PriorityQueue类与普通队列最主要的区别就是多了个比较器。一般情况下,都是自己通过实现Comparator接口写一个比较器,在new 优先队列时将这个比较器丢进去就ok了,
构造方法中就有 PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
使用指定的初始容量创建一个 PriorityQueue
,并根据指定的比较器对元素进行排序。
2、虽然优先队列在放入元素时,会通过其中的比较器进行比较后,放到相应的位置。但是至于它内部是怎么比较的,怎么放的,我还没去深究,但是在这里我知道,虽然题目是说先通过优先级进行存放,然后通过进队顺序存放,听起来只要考虑
优先级排序就行了,主观上就会以为只要优先级相同时,也就是compare返回0,它就会放在同一优先级,但先进来的元素后面,其实不然,并不是这样的,这里必须要通过进队的序列号来比较后才能达到想要的目的。
import java.util.Comparator; import java.util.PriorityQueue; import java.util.Scanner; public class P1509 { public static void main(String[] args) { Scanner sc=new Scanner(System.in); PriorityQueue<Message> priorityQue=new PriorityQueue<Message>(6000,new MesCmp());//优先队列 Message messg;//messg类 int count=0; while(sc.hasNext()){ String operate=sc.next(); if(operate.charAt(0)=='G'){//出队 if(priorityQue.isEmpty()){ System.out.println("EMPTY QUEUE!"); }else{ System.out.println(priorityQue.poll()); } }else{//入队 messg=new Message(sc.next(), sc.nextInt(), sc.nextInt(),count++); priorityQue.add(messg); } } } } class Message{ String name; int value; int priority; int id; public Message(String name, int value, int priority,int id) { this.name = name; this.value = value; this.priority = priority; this.id = id; } public String toString() { return name + " " + value; } } class MesCmp implements Comparator<Message>{ public int compare(Message m1, Message m2) { if(m1.priority<m2.priority){ return -1; }else if(m1.priority>m2.priority){ return 1; }else{ //这里如果没有id的比较,那顺序就会出错 if(m1.id<m2.id){ return -1; }else if(m1.id>m2.id){ return 1; }else{ return 0; } } } }