添加元素到优先队列时遇到了一些问题。

huangapple go评论72阅读模式
英文:

Having Some problem when adding element to Priority Queue

问题

I am working with Priority Queue problem in this link Hackkerank Problem

My Student class was created follow by OOP patterns which have constructor with 3 attributes (id, Name, cgpa) and some Getter method

My Priorities

class Priorities{
        private List<Student> list_student = new ArrayList<>();

    class  CheckCondition implements Comparator<Student>{


        @Override
        public int compare(Student o1, Student o2) {
            if(o1.getCGPA() < o2.getCGPA()){
                return 1;
            }else if(o1.getCGPA() > o2.getCGPA()){
                return -1;
            }else{
                if(o1.getName().compareTo(o2.getName()) < 0) {
                    return 1;
                }else if(o1.getName().compareTo(o2.getName()) > 0){
                    return -1;
                }else {
                    if(o1.getID() < o2.getID()){
                        return -1;
                    }else {
                        return 1;
                    }
                }
            }

        }
    }


    public List<Student> getStudents(List<String> events, int capacity){
        Queue<Student> stringQueue = new PriorityQueue<>(capacity, new CheckCondition());
        if(events.isEmpty()){
            System.out.println("EMPTY");
        }
        for(String element: events){
            List<String> stringList = List.of(element.split(" "));
            if(stringList.get(0).equalsIgnoreCase("ENTER")){
                Student new_student = new   Student(Integer.parseInt(stringList.get(3)), stringList.get(1), Double.parseDouble(stringList.get(2)));
                stringQueue.add(new_student);
            }if(stringList.get(0).equalsIgnoreCase("SERVED") ){
                stringQueue.poll();
            }
        }
        stringQueue.stream().forEach(element -> list_student.add(element));

        return list_student;

    }
}

My Main


public class Main {
public static void main(String[] args) {
         Scanner sc = new Scanner(System.in);
         List<String> events = new ArrayList<>();
         Integer capacity = sc.nextInt();
         sc.nextLine();

        for (int i = 0; i < capacity; i++) {
            events.add(sc.nextLine());
        }
    
        Priorities priorities = new Priorities();
        List<Student> students = priorities.getStudents(events, capacity);
    
        for(Student element: students){
            System.out.println(element.getName());
        }
    
    }

}

So When I try with the test case in Hackerrank, My result instead of as expect, I change slightly in the end of the Queue

Expect result:


Dan
Ashley
**Shafaet
Maria**

Actual result:


Dan
Ashley
**Maria
Shafaet**

Can anyone help me to figure out why I can have this result as I try many times but it showed an abnormal case when program add the "Anik" student in the Queue which also change to position or 2 student "Shafaet" and "Maria".

Thank everyone so much

英文:

I am working with Priority Queue problem in this link
Hackkerank Problem

My Student class was created follow by OOP patterns which have constructor with 3 attributes (id, Name, cgpa) and some Getter method

My Priorities

class Priorities{
private List<Student> list_student = new ArrayList<>();
class  CheckCondition implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
if(o1.getCGPA() < o2.getCGPA()){
return 1;
}else if(o1.getCGPA() > o2.getCGPA()){
return -1;
}else{
if(o1.getName().compareTo(o2.getName()) < 0) {
return 1;
}else if(o1.getName().compareTo(o2.getName()) > 0){
return -1;
}else {
if(o1.getID() < o2.getID()){
return -1;
}else {
return 1;
}
}
}
}
}
public List<Student> getStudents(List<String> events, int capacity){
Queue<Student> stringQueue = new PriorityQueue<>(capacity, new CheckCondition());
if(events.isEmpty()){
System.out.println("EMPTY");
}
for(String element: events){
List<String> stringList = List.of(element.split(" "));
if(stringList.get(0).equalsIgnoreCase("ENTER")){
Student new_student = new   Student(Integer.parseInt(stringList.get(3)), stringList.get(1), Double.parseDouble(stringList.get(2)));
stringQueue.add(new_student);
}if(stringList.get(0).equalsIgnoreCase("SERVED") ){
stringQueue.poll();
}
}
stringQueue.stream().forEach(element -> list_student.add(element));
return list_student;
}
}

My Main


public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
List<String> events = new ArrayList<>();
Integer capacity = sc.nextInt();
sc.nextLine();
for (int i = 0; i < capacity; i++) {
events.add(sc.nextLine());
}
Priorities priorities = new Priorities();
List<Student> students = priorities.getStudents(events, capacity);
for(Student element: students){
System.out.println(element.getName());
}
}
}

So When I try with the test case in Hackerrank, My result instead of as expect, I change slightly in the end of the Queue

Expect result:


Dan
Ashley
**Shafaet
Maria**

Actual result:


Dan
Ashley
**Maria
Shafaet**

Can anyone help me to figure out why I can have this result as I try many times but it showed an abnormal case when program add the "Anik" student in the Queue which also change to position or 2 student "Shafaet" and "Maria".

Thank everyone so much

答案1

得分: 2

名称应按升序排序,因此当 o1 的名称在词典上位于 o2 之前时,应返回 -1

if (o1.getName().compareTo(o2.getName()) < 0) {
    return -1;
} else if (o1.getName().compareTo(o2.getName()) > 0) {
    return 1;
}

此外,当id相等时,应返回 0

另一个主要问题是 PriorityQueuestream 方法不保证顺序。您可以轮询所有元素并添加到 List 中。

while (!stringQueue.isEmpty())
    list_student.add(stringQueue.poll());

请注意,使用 Comparator.comparing 方法可以更简单地编写 Comparator

Queue<Student> stringQueue = new PriorityQueue<>(capacity, 
        Comparator.comparingDouble(Student::getCGPA).reversed()
            .thenComparing(Student::getName)
            .thenComparing(Student::getID));
英文:

Names should be sorted in ascending order, so you should return -1 when o1's name comes before o2 lexicographically.

if (o1.getName().compareTo(o2.getName()) &lt; 0) {
	return -1;
} else if (o1.getName().compareTo(o2.getName()) &gt; 0) {
	return 1;
}

Also, you should return 0 when the ids are equal.

Another major issue is that the stream method for PriorityQueue does not guarantee order. You could poll all of the elements and add to the List instead.

while (!stringQueue.isEmpty())
	list_student.add(stringQueue.poll());

Note that the Comparator can be written a lot more simply using the Comparator.comparing methods:

Queue&lt;Student&gt; stringQueue = new PriorityQueue&lt;&gt;(capacity, 
		Comparator.comparingDouble(Student::getCGPA).reversed()
            .thenComparing(Student::getName)
			.thenComparing(Student::getID));

huangapple
  • 本文由 发表于 2023年7月13日 12:38:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76675977.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定