অগ্রাধিকারের কিউয়ে সর্বাধিক অগ্রাধিকারের পরিবর্তন করুন


123

পূর্ণসংখ্যার জাভাতে আমার অগ্রাধিকারের সারি রয়েছে:

 PriorityQueue<Integer> pq= new PriorityQueue<Integer>();

আমি যখন ফোন pq.poll()করি তখন আমি ন্যূনতম উপাদান পাই।

প্রশ্ন: সর্বাধিক উপাদান পেতে কোডটি কীভাবে পরিবর্তন করবেন?


4
আমি মনে করি আপনার সেই কনস্ট্রাক্টর ব্যবহার করা উচিত যা এর জন্য তুলনামূলক গ্রহণ করে। বিপরীত তুলনাকারীটি সংগ্রহ করতে কালেকশনস.রেভারস অর্ডার ব্যবহার করুন।
এডউইন ডালোরজো

1
আপনাকে একটি তুলনামূলক পাস করতে হবে। দেখতে stackoverflow.com/questions/683041/...
DarthVader

এটি সাহায্য করতে পারে: tech693.blogspot.com/2018/09/…
জাভা গুরু

উত্তর:


232

এই মত সম্পর্কে:

PriorityQueue<Integer> queue = new PriorityQueue<>(10, Collections.reverseOrder());
queue.offer(1);
queue.offer(2);
queue.offer(3);
//...

Integer val = null;
while( (val = queue.poll()) != null) {
    System.out.println(val);
}

Collections.reverseOrder()একটি উপলব্ধ Comparatorযে উপাদান বাছাই হবে PriorityQueueএই ক্ষেত্রে তাদের প্রাকৃতিক শৃঙ্খলার জন্য সত্যিই অপর পিঠ যাতে।


14
Collections.reverseOrder()তুলনামূলক নিতে ওভারলোড করা হয়, তাই আপনি কাস্টম অবজেক্টগুলির তুলনা করলে এটিও কাজ করে।
উড়ন্ত ভেড়া

14
জাভা 8 এর অগ্রাধিকারকুইয়েতে একটি নতুন কনস্ট্রাক্টর রয়েছে, যা কেবল তুলনামূলক হিসাবে যুক্তি হিসাবে গ্রহণ করে PriorityQueue(Comparator<? super E> comparator)
অভিষেক্নিরমাল

75

আপনি জাভা 8 সাল থেকে ল্যাম্বডা এক্সপ্রেশন ব্যবহার করতে পারেন।

নীচের কোডটি 10 ​​টি বড় আকারের মুদ্রণ করবে।

// There is overflow problem when using simple lambda as comparator, as pointed out by Фима Гирин.
// PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> y - x);

PriorityQueue<Integer> pq =new PriorityQueue<>((x, y) -> Integer.compare(y, x));

pq.add(10);
pq.add(5);
System.out.println(pq.peek());

ল্যাম্বদা ফাংশনটি ইনপুট পরামিতি হিসাবে দুটি পূর্ণসংখ্যার গ্রহণ করবে, একে অপরের থেকে বিয়োগ করে এবং পাটিগণিতের ফলাফলটি ফিরিয়ে দেবে। ল্যাম্বদা ফাংশন কার্যকরী ইন্টারফেস প্রয়োগ করে Comparator<T>,। (এটি কোনও বেনাম শ্রেণীর বা পৃথক বাস্তবায়নের বিপরীতে এটি জায়গায় ব্যবহার করা হয়))


ল্যাম্বদা ফাংশন, এর ইনপুট প্যারামিটারগুলির নাম দেয় x এবং y এবং yx ফেরত দেয় যা মূলত ইন্টি তুলনাকারী ক্লাসটি xy ফেরান ব্যতীত কি করে
এডি বাইস

15
(x, y) -> y - xওভারফ্লোর কারণে তুলনাকারীর মতো দীর্ঘ দীর্ঘসংখ্যার পক্ষে উপযুক্ত নাও হতে পারে। উদাহরণস্বরূপ, সংখ্যা y = পূর্ণসংখ্যা M MIN_VALUE এবং x = 5 এর ইতিবাচক সংখ্যার ফলাফল। এটি ব্যবহার করা ভাল new PriorityQueue<>((x, y) -> Integer.compare(y, x))। যদিও, আরও ভাল সমাধানটি ব্যবহারের জন্য @ এডউইন ডালোরজো দিয়েছেন Collections.reverseOrder()
12 21

1
@। এটি সত্য। -2147483648 - 1 2147483647 হয়ে
Guangtong সেন

27

আপনি একটি কাস্টম Comparatorঅবজেক্ট সরবরাহ করতে পারেন যা বিপরীত ক্রমে উপাদানগুলির তালিকা করে:

PriorityQueue<Integer> pq = new PriorityQueue<Integer>(defaultSize, new Comparator<Integer>() {
    public int compare(Integer lhs, Integer rhs) {
        if (lhs < rhs) return +1;
        if (lhs.equals(rhs)) return 0;
        return -1;
    }
});

এখন, অগ্রাধিকার সারি তার সমস্ত তুলনা বিপরীত করবে, তাই আপনি ন্যূনতম উপাদানটির চেয়ে সর্বাধিক উপাদানটি পাবেন।

আশাকরি এটা সাহায্য করবে!


5
সম্ভবত সর্বাধিক অগ্রাধিকারের জন্য q l l <<< retrs +1; আপনি এখানে যা লিখেছেন তা আমার পরীক্ষার পরে ন্যূনতম কিউ
sivi

বিপরীত মুদ্রণের জন্য, এটি যদি সর্বোচ্চ উপাদানগুলিকে প্রথমে অগ্রাধিকারের কাতারে মুদ্রণ করা হয় তবে তা হওয়া উচিতif (rhs < lhs) return +1; if (rhs > lhs) return -1;
টিয়া

@ দীক্ষা আমি বিশ্বাস করি যে আমার কাছে কোডটি আপনি পোস্ট করছেন তার সমান। আমি সেক্ষেত্রে কম-সম্পর্কের চেয়ে বৃহত্তর সম্পর্কের ব্যবহার করেছি।
টেম্পলেটটিফাইফ

4
আসলে, আমার ভুল .. আমি বোঝাতে চাইছিলাম এটি এমন হওয়া উচিত:if (lhs < rhs) return +1; if (lhs > rhs) return -1;
টিয়া

1
@ শ্রীকান্ত প্রভু ভাল ধরা - এখন তা স্থির!
টেম্পলেটটিফাইফ

14
PriorityQueue<Integer> pq = new PriorityQueue<Integer> (
  new Comparator<Integer> () {
    public int compare(Integer a, Integer b) {
       return b - a;
    }
  }
);

সমস্যাটা কি ?
সিএমইদিনা

এটি নিখুঁত এবং এক মিনিটের গাদাকে সর্বাধিক apালিতে পরিণত করে যা বলা হয়েছিল ঠিক তা করে।
কামরান

2
ব্যবহার b-aহতে পারে overflowতাই এটি ব্যবহার এড়িয়ে চলা উচিত এবং ব্যবহার করা উচিত Collections.reverseOrder();একটি comparator হিসাবে অথবা সঙ্গে বিএ প্রতিস্থাপন Integer.compare(a,b);যা যোগ করা হয়েছেJava 8
যুগ সিং

10

জাভা 8+ এ আপনি এই পদ্ধতির একটির মাধ্যমে সর্বাধিক অগ্রাধিকারের সারি তৈরি করতে পারেন:

পদ্ধতি 1:

PriorityQueue<Integer> maxPQ = new PriorityQueue<>(Collections.reverseOrder()); 

পদ্ধতি 2:

PriorityQueue<Integer> maxPQ = new PriorityQueue<>((a,b) -> b - a); 

পদ্ধতি 3:

PriorityQueue<Integer> maxPQ = new PriorityQueue<>((a,b) -> b.compareTo(a)); 

8

অগ্রাধিকারের সারির উপাদানগুলি তাদের প্রাকৃতিক ক্রম অনুসারে অর্ডার করা হয়, বা সারি নির্মাণের সময় সরবরাহকারী কোনও তুলক দ্বারা।

তুলনাকারীর তুলনা পদ্ধতিটি ওভাররাইড করা উচিত।

int compare(T o1, T o2)

ডিফল্ট তুলনা পদ্ধতিটি প্রথম আর্গুমেন্টটি দ্বিতীয়টির চেয়ে কম, সমান বা তার চেয়ে বড় হিসাবে একটি negativeণাত্মক পূর্ণসংখ্যা, শূন্য বা ধনাত্মক পূর্ণসংখ্যা দেয়।

জাভা প্রদত্ত ডিফল্ট অগ্রাধিকারের মানটি হ'ল ন্যূনতম হিপ, আপনি যদি একটি সর্বাধিক হিপ চান তবে নিম্নলিখিত কোডগুলি

public class Sample {
    public static void main(String[] args) {
        PriorityQueue<Integer> q = new PriorityQueue<Integer>(new Comparator<Integer>() {

            public int compare(Integer lhs, Integer rhs) {
                if(lhs<rhs) return +1;
                if(lhs>rhs) return -1;
                return 0;
            }
        });
        q.add(13);
        q.add(4);q.add(14);q.add(-4);q.add(1);
        while (!q.isEmpty()) {
            System.out.println(q.poll());
        }
    }

}

তথ্যসূত্র: https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html#comparator ()


4

এখানে জাভাতে ম্যাক্স-হ্যাপের একটি নমুনা রয়েছে:

PriorityQueue<Integer> pq1= new PriorityQueue<Integer>(10, new Comparator<Integer>() {
public int compare(Integer x, Integer y) {
if (x < y) return 1;
if (x > y) return -1;
return 0;
}
});
pq1.add(5);
pq1.add(10);
pq1.add(-1);
System.out.println("Peek: "+pq1.peek());

আউটপুট 10 হবে


4

এটি জাভা 8 এর নীচের কোড দ্বারা অর্জন করা যেতে পারে যা এমন একটি কনস্ট্রাক্টর চালু করেছে যা কেবল তুলনামূলক লাগে takes

PriorityQueue<Integer> maxPriorityQ = new PriorityQueue<Integer>(Collections.reverseOrder());


3

অগ্রাধিকারের কিউএইএক্সকে MAX অগ্রাধিকারকুই পদ্ধতি 1 তে পরিবর্তন করুন: ক্যু পিকিউ = নতুন অগ্রাধিকারকুই <> (সংগ্রহশালার রিভার্সআর্ডার ()); পদ্ধতি 2: সারি pq1 = নতুন অগ্রাধিকারকুই <> ((ক, খ) -> খ - ক); আসুন কয়েকটি উদাহরণ দেখুন:

public class Example1 {
    public static void main(String[] args) {

        List<Integer> ints = Arrays.asList(222, 555, 666, 333, 111, 888, 777, 444);
        Queue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
        pq.addAll(ints);
        System.out.println("Priority Queue => " + pq);
        System.out.println("Max element in the list => " + pq.peek());
        System.out.println("......................");
        // another way
        Queue<Integer> pq1 = new PriorityQueue<>((a, b) -> b - a);
        pq1.addAll(ints);
        System.out.println("Priority Queue => " + pq1);
        System.out.println("Max element in the list => " + pq1.peek());
        /* OUTPUT
          Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222]
          Max element in the list => 888
          ......................
           Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222]
           Max element in the list => 888

         */


    }
}

আসুন একটি বিখ্যাত সাক্ষাত্কারের সমস্যাটি গ্রহণ করা যাক: অগ্রাধিকারের কিউ ব্যবহার করে একটি অ্যারেতে Kth বৃহত্তম এলিমেন্ট

public class KthLargestElement_1{
    public static void main(String[] args) {

        List<Integer> ints = Arrays.asList(222, 555, 666, 333, 111, 888, 777, 444);
        int k = 3;
        Queue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
        pq.addAll(ints);
        System.out.println("Priority Queue => " + pq);
        System.out.println("Max element in the list => " + pq.peek());
        while (--k > 0) {
            pq.poll();
        } // while
        System.out.println("Third largest => " + pq.peek());
/*
 Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222]
Max element in the list => 888
Third largest => 666

 */
    }
}

অন্য উপায় :

public class KthLargestElement_2 {
    public static void main(String[] args) {
        List<Integer> ints = Arrays.asList(222, 555, 666, 333, 111, 888, 777, 444);
        int k = 3;

        Queue<Integer> pq1 = new PriorityQueue<>((a, b) -> b - a);
        pq1.addAll(ints);
        System.out.println("Priority Queue => " + pq1);
        System.out.println("Max element in the list => " + pq1.peek());
        while (--k > 0) {
            pq1.poll();
        } // while
        System.out.println("Third largest => " + pq1.peek());
        /*
          Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222] 
          Max element in the list => 888 
          Third largest => 666

         */
    }
}

আমরা দেখতে পাচ্ছি, উভয়ই একই ফলাফল দিচ্ছে।


3

এটি ব্যবহার করে অর্জন করা যেতে পারে

PriorityQueue<Integer> pq = new PriorityQueue<Integer>(Collections.reverseOrder());

1

আমি কেবল ডাবল হিপ সাজানোর ন্যূনতম সর্বাধিক ম্যাক্সে উভয় তুলনাকারীর উপর একটি মন্টে-কার্লো সিমুলেশন চালিয়েছি এবং তারা উভয়ই একই ফলতে এসেছিল:

এগুলি আমি ব্যবহার করা সর্বাধিক তুলনামূলক:

(ক) অন্তর্নির্মিত তুলনা সংগ্রহ

 PriorityQueue<Integer> heapLow = new PriorityQueue<Integer>(Collections.reverseOrder());

(খ) কাস্টম তুলনা

PriorityQueue<Integer> heapLow = new PriorityQueue<Integer>(new Comparator<Integer>() {
    int compare(Integer lhs, Integer rhs) {
        if (rhs > lhs) return +1;
        if (rhs < lhs) return -1;
        return 0;
    }
});

বিপরীত মুদ্রণের জন্য, এটি যদি সর্বোচ্চ উপাদানগুলিকে প্রথমে অগ্রাধিকারের কাতারে মুদ্রণ করা হয় if (rhs < lhs) return +1;তবে এটি হওয়া উচিত যদি (আরএইচএস> এলএইচ) ফেরত -১;
টিয়া

আপনি যদি চান এটি সম্পাদনা করতে পারেন। আপনি যা লিখেছেন তা নিশ্চিত করার মতো সময় আমার নেই। আমার সেটআপে আমি যা লিখেছিলাম তা সঠিক ছিল
sivi

1

আপনি এর মতো কিছু চেষ্টা করতে পারেন:

PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> -1 * Integer.compare(x, y));

যা আপনার অন্য কোনও বেস তুলনা ফাংশনের জন্য কাজ করে।



0

আপনি বিপরীত চিহ্ন সহ উপাদানগুলিকে ঠেলে দেওয়ার চেষ্টা করতে পারেন। উদাহরণস্বরূপ: a = 2 & b = 5 যোগ করতে এবং তারপরে b = 5 জরিপ করুন।

PriorityQueue<Integer>  pq = new PriorityQueue<>();
pq.add(-a);
pq.add(-b);
System.out.print(-pq.poll());

একবার আপনি কাতারের মাথাটি পোল করুন, আপনার ব্যবহারের জন্য সাইনটি বিপরীত করুন। এটি 5 (বৃহত্তর উপাদান) মুদ্রণ করবে। নিষ্পাপ বাস্তবায়নে ব্যবহার করা যেতে পারে। অবশ্যই একটি নির্ভরযোগ্য ফিক্স না। আমি এটি সুপারিশ না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.