আমি কীভাবে অগ্রাধিকারের কিউ ব্যবহার করব?


374

PriorityQueueআমি যা চাই তা সাজানোর জন্য আমি কীভাবে তা পেতে পারি ?

এছাড়াও, পদ্ধতি offerএবং addপদ্ধতির মধ্যে কোনও পার্থক্য রয়েছে ?

উত্তর:


449

কনস্ট্রাক্টর ওভারলোড ব্যবহার করুন Comparator<? super E> comparatorযা আপনার তুল্যক্রমের জন্য উপযুক্ত উপায়ে তুলনা করে এমন একটি তুলনাকারীতে পাস করে এবং পাস করে। আপনি কীভাবে বাছাই করতে চান তার উদাহরণ যদি আপনি দেন তবে আমরা নিশ্চিত না হলে তুলনাকারী বাস্তবায়নের জন্য আমরা কয়েকটি নমুনা কোড সরবরাহ করতে পারি। (যদিও এটি বেশ সোজা।

যেমনটি অন্য কোথাও বলা হয়েছে: offerএবং addকেবলমাত্র ইন্টারফেসের বিভিন্ন পদ্ধতির বাস্তবায়ন। JDK উৎস আমি পেয়েছেন সালে addআহ্বান offer। যদিও addএবং offerআছে সম্ভাব্য ক্ষমতা সাধারণ কারণে বিভিন্ন আচরণ offerনির্দেশ করে যে মান আকার সীমাবদ্ধতার কারণে যোগ করা যাবে না, এই পার্থক্য মধ্যে অপ্রাসঙ্গিক PriorityQueueযা সীমাবদ্ধ নয়।

এখানে স্ট্রিং দৈর্ঘ্যের দ্বারা বাছাই করা একটি অগ্রাধিকারের সারির উদাহরণ:

// Test.java
import java.util.Comparator;
import java.util.PriorityQueue;

public class Test {
    public static void main(String[] args) {
        Comparator<String> comparator = new StringLengthComparator();
        PriorityQueue<String> queue = new PriorityQueue<String>(10, comparator);
        queue.add("short");
        queue.add("very long indeed");
        queue.add("medium");
        while (queue.size() != 0) {
            System.out.println(queue.remove());
        }
    }
}

// StringLengthComparator.java
import java.util.Comparator;

public class StringLengthComparator implements Comparator<String> {
    @Override
    public int compare(String x, String y) {
        // Assume neither string is null. Real code should
        // probably be more robust
        // You could also just return x.length() - y.length(),
        // which would be more efficient.
        if (x.length() < y.length()) {
            return -1;
        }
        if (x.length() > y.length()) {
            return 1;
        }
        return 0;
    }
}

এখানে ফলাফল:

সংক্ষিপ্ত

মধ্যম

সত্যিই খুব দীর্ঘ


7
হুম ... সবেমাত্র লক্ষ্য করেছেন ... ترجیح কুই ডটকম্পারেটর () "এই সংগ্রহটি অর্ডার করার জন্য ব্যবহৃত তুলনাকারীকে ফেরত দেয়, বা যদি সংগ্রহটি এর উপাদানগুলির প্রাকৃতিক ক্রম অনুসারে বাছাই করা হয় তবে তুলনাযোগ্য ব্যবহার করা হয় (তুলনামূলক ব্যবহার করে)" ull তার মানে কি আমি ঠিক আমার ক্লাসে তুলনামূলক প্রয়োগ করতে পারি?
সুইভিশ

7
আপনি করতে পারেন, হ্যাঁ। যদিও আপনার ক্লাসের জন্য একক প্রাকৃতিক সাজানোর অর্ডার না থাকলে আমি তা করব না। যদি সেখানে থাকে তবে এটিই সঠিক জিনিস :)
জন স্কিটি 20

8
compareশুধু বাস্তবায়ন হওয়া উচিত নয় return x.length() - y.length()? (শাখার পূর্বাভাস এড়ানো)
ফ্রাঙ্কি

7
@ ফ্র্যাঙ্কি: এটি হতে পারে, হ্যাঁ - যদিও আমি বলব যে এটি বোঝা কিছুটা কঠিন, এবং উত্তরের উদ্দেশ্যটি প্রদর্শন করছে যে এটি কীভাবে কাজ করে। যদিও আমি একটি মন্তব্য যুক্ত করব।
জন স্কিটি

2
@ কারেলজি: যতক্ষণ না আপনি পার্থক্য সম্পর্কে অবহিত হন ততক্ষণ আমি এটিকে বেশি গুরুত্ব দেবে বলে আমি মনে করি না । আমি মনে করি আপনি যদি add()অ্যাডিং অপারেশনের জন্য ব্যবহার করেন, তবে remove()বোধশক্তি বোধ করেন; যদি আমি ব্যবহার offer()করতাম আমি সম্ভবত ব্যবহার করতাম poll()... তবে এটি কেবল একটি ব্যক্তিগত পছন্দ।
জন স্কিটি

68

জাভা 8 সমাধান

আমরা জাভা ৮ তে ব্যবহার lambda expressionবা method referenceপ্রবর্তন করতে পারি In ক্ষেত্রে যদি আমাদের কিছু স্ট্রিং মান অগ্রাধিকার কাতারে সঞ্চিত থাকে (ধারণ ক্ষমতা 5) আমরা ইনলাইন তুলক সরবরাহ করতে পারি (স্ট্রিংয়ের দৈর্ঘ্যের উপর ভিত্তি করে):

ল্যাম্বডা এক্সপ্রেশন ব্যবহার করে

PriorityQueue<String> pq=
                    new PriorityQueue<String>(5,(a,b) -> a.length() - b.length());

পদ্ধতি রেফারেন্স ব্যবহার করে

PriorityQueue<String> pq=
                new PriorityQueue<String>(5, Comparator.comparing(String::length));

তারপরে আমরা তাদের যেকোনটি ব্যবহার করতে পারি:

public static void main(String[] args) {
        PriorityQueue<String> pq=
                new PriorityQueue<String>(5, (a,b) -> a.length() - b.length());
       // or pq = new PriorityQueue<String>(5, Comparator.comparing(String::length));
        pq.add("Apple");
        pq.add("PineApple");
        pq.add("Custard Apple");
        while (pq.size() != 0)
        {
            System.out.println(pq.remove());
        }
    }

এটি মুদ্রণ করবে:

Apple
PineApple
Custard Apple

অর্ডারটি বিপরীত করতে (এটি সর্বাধিক-অগ্রাধিকারের কাতারে পরিবর্তন করতে) কেবল ইনলাইন তুলকরে অর্ডার পরিবর্তন করুন বা reversedহিসাবে ব্যবহার করুন :

PriorityQueue<String> pq = new PriorityQueue<String>(5, 
                             Comparator.comparing(String::length).reversed());

আমরা এটিও ব্যবহার করতে পারি Collections.reverseOrder:

PriorityQueue<Integer> pqInt = new PriorityQueue<>(10, Collections.reverseOrder());
PriorityQueue<String> pq = new PriorityQueue<String>(5, 
                Collections.reverseOrder(Comparator.comparing(String::length))

সুতরাং আমরা দেখতে পাচ্ছি যে Collections.reverseOrderতুলনামূলক তুলনায় অতিরিক্ত লোড হয়েছে যা কাস্টম অবজেক্টগুলির জন্য দরকারী। reversedআসলে ব্যবহারসমূহ Collections.reverseOrder:

default Comparator<T> reversed() {
    return Collections.reverseOrder(this);
}

অফার () বনাম অ্যাড ()

অনুযায়ী ডক

অফার পদ্ধতিটি সম্ভব হলে কোনও উপাদান সন্নিবেশ করায় অন্যথায় মিথ্যা ফিরিয়ে দেয়। এটি কালেকশন.এডিডি পদ্ধতি থেকে পৃথক, যা কেবল একটি চেক না করা ব্যতিক্রম ছুঁড়ে দিয়ে কোনও উপাদান যুক্ত করতে ব্যর্থ হতে পারে। অফার পদ্ধতিটি ব্যবহারের জন্য ডিজাইন করা হয় যখন ব্যর্থতা স্বাভাবিক হয়, ব্যতিক্রমী ঘটনার পরিবর্তে, উদাহরণস্বরূপ, স্থির-ক্ষমতা (বা "সীমাবদ্ধ") সারিগুলিতে।

সক্ষমতা-সীমাবদ্ধ ক্যু ব্যবহার করার সময়, অফার () সাধারণত () যুক্ত করা ভাল, যা কেবলমাত্র ব্যতিক্রম ছুঁড়ে দিয়ে কোনও উপাদান সন্নিবেশ করতে ব্যর্থ হতে পারে। আর PriorityQueue একটি সীমাবদ্ধ অগ্রাধিকার একটি অগ্রাধিকার গাদা উপর ভিত্তি করে কিউ।


আমি কি ধরে নিচ্ছি যে 5কিউ শুরু করার ক্ষমতা নির্দেশ করে?
নীল

1
@ নীল হ্যাঁ, আমি এখনই উত্তরে এটি আরও স্পষ্ট করে
দিয়েছি

1
জাভা-র 8 ম সংস্করণটি ভাষাতে কখনও ঘটে যাওয়া সেরা জিনিস ছিল
গ্যাব্রিয়েলবিবি

1
সুস্পষ্ট উদাহরণ সহ খুব সুন্দর ব্যাখ্যা।
বিশ্ব রত্না

24

কেবল কনস্ট্রাক্টরেরComparator কাছে উপযুক্ত পাস করুন :

PriorityQueue(int initialCapacity, Comparator<? super E> comparator)

এর মধ্যে offerএবং addকেবলমাত্র ইন্টারফেসের মধ্যে পার্থক্য । offerএর অন্তর্গত Queue<E>, যেখানে addমূলত Collection<E>ইন্টারফেসে দেখা যায় । এছাড়াও উভয় পদ্ধতি হুবহু একই কাজ করে - নির্দিষ্ট উপাদানটিকে অগ্রাধিকারের কাতারে সন্নিবেশ করান।


7
বিশেষত, অ্যাড () একটি ব্যতিক্রম ছুঁড়ে দেয় যদি ক্ষমতা সীমাবদ্ধতা আইটেমটিকে কাতারে যুক্ত হতে বাধা দেয় এবং অফারগুলি মিথ্যা দেয়। যেহেতু অগ্রাধিকারের কিউইউগুলির সর্বাধিক ক্ষমতা নেই, তাই পার্থক্যটি মোট।
জেমস

এটি অ্যাড () এবং অফার () এর মধ্যে খুব স্পষ্ট পার্থক্য .. এবং অ্যাড () যাইহোক বাস্তবায়ন করা দরকার ছিল!
হোয়াইটহ্যাট

19

ক্যু API থেকে :

অফার পদ্ধতিটি সম্ভব হলে কোনও উপাদান সন্নিবেশ করায় অন্যথায় মিথ্যা ফিরিয়ে দেয়। এটি কালেকশন.এডিডি পদ্ধতি থেকে পৃথক, যা কেবল একটি চেক না করা ব্যতিক্রম ছুঁড়ে দিয়ে কোনও উপাদান যুক্ত করতে ব্যর্থ হতে পারে। অফার পদ্ধতিটি ব্যবহারের জন্য ডিজাইন করা হয় যখন ব্যর্থতা স্বাভাবিক হয়, ব্যতিক্রমী ঘটনার পরিবর্তে, উদাহরণস্বরূপ, স্থির-ক্ষমতা (বা "সীমাবদ্ধ") সারিগুলিতে।


12

জাভাডোক হিসাবে ঘোষণা হিসাবে পৃথক:

public boolean add(E e) {
    return offer(e);
}

6

কেবল add()বনাম offer()প্রশ্নের উত্তর দেওয়ার জন্য (যেহেতু অন্যটির সঠিকভাবে ইমোর উত্তর দেওয়া হয়েছে, এবং এটি হতে পারে না):

ইন্টারফেস ক্যুতে জাভডোকের মতে , "অফার পদ্ধতিটি সম্ভব হলে কোনও উপাদান সন্নিবেশ করে, অন্যথায় মিথ্যা ফিরিয়ে দেয় This এটি কালেকশন.এডডি পদ্ধতি থেকে পৃথক, যা কেবল একটি চেক না করা ব্যতিক্রম ছুঁড়ে দিয়ে উপাদান যুক্ত করতে ব্যর্থ হতে পারে offer অফার পদ্ধতিটি ডিজাইন করা হয়েছে ব্যর্থতা ব্যতিক্রমী ঘটনার পরিবর্তে স্বাভাবিক হওয়ার ক্ষেত্রে ব্যবহার করুন, উদাহরণস্বরূপ, স্থির-ক্ষমতা (বা "চৌম্বক") সারিগুলিতে ""

এর অর্থ আপনি যদি উপাদানটি যুক্ত করতে পারেন (যা সর্বদা অগ্রাধিকারের ক্ষেত্রে হওয়া উচিত) তবে তারা ঠিক একই রকম কাজ করে। তবে আপনি যদি উপাদানটি যুক্ত করতে না পারেন তবে offer()আপনাকে একটি সুন্দর এবং সুন্দর falseপ্রত্যাবর্তন দেবে, যখন add()আপনি আপনার কোডটিতে চান না এমন একটি বাজে অনাবৃত ব্যতিক্রম ছোঁড়ে। যদি যুক্ত করতে ব্যর্থতা মানে কোডটি ইচ্ছাকৃতভাবে কাজ করছে এবং / অথবা এটি এমন কিছু যা আপনি সাধারণত যাচাই করেন তবে ব্যবহার করুন offer()। যোগ করতে ব্যর্থতার অর্থ যদি কিছু ভাঙা যায়, সংগ্রহ ইন্টারফেসের নির্দিষ্টকরণadd() অনুসারে ছুঁড়ে দেওয়া ব্যতিক্রমগুলি ব্যবহার এবং পরিচালনা করুন ।

তারা উভয়ই এইভাবে কুই ইন্টারফেসে চুক্তিটি পূর্ণ পূরণের জন্য প্রয়োগ করা হয়েছে যা offer()একটি false( ক্ষমতা-সীমাবদ্ধ কাতারে পছন্দসই পদ্ধতি) ফিরিয়ে দিয়ে ব্যর্থতা নির্দিষ্ট করে এবং সংগ্রহ ইন্টারফেসে চুক্তিটি বজায় রাখে যা নির্দিষ্টভাবে add()ব্যতিক্রম ছুঁড়ে ফেলে ব্যর্থ হয়

যাইহোক, আশা করি যে প্রশ্নের অন্তত অংশটি স্পষ্ট করে।


6

এখানে, আমরা ব্যবহারকারীর সংজ্ঞায়িত তুলক সংজ্ঞায়িত করতে পারি:

কোডের নীচে:

 import java.util.*;
 import java.util.Collections;
 import java.util.Comparator; 


 class Checker implements Comparator<String>
 {
    public int compare(String str1, String str2)
    {
        if (str1.length() < str2.length()) return -1;
        else                               return 1;
    }
 }


class Main
{  
   public static void main(String args[])
    {  
      PriorityQueue<String> queue=new PriorityQueue<String>(5, new Checker());  
      queue.add("india");  
      queue.add("bangladesh");  
      queue.add("pakistan");  

      while (queue.size() != 0)
      {
         System.out.printf("%s\n",queue.remove());
      }
   }  
}  

আউটপুট:

   india                                               
   pakistan                                         
   bangladesh

অফারের মধ্যে পার্থক্য এবং পদ্ধতিগুলি যুক্ত করুন: লিংক


1
যদি তারা সমান হয়।
nycynik

4

এটি পাস a Comparator। আপনার পছন্দসই ধরণের জায়গায় পূরণ করুনT

ল্যাম্বডাস (জাভা 8+) ব্যবহার করে:

int initialCapacity = 10;
PriorityQueue<T> pq = new PriorityQueue<>(initialCapacity, (e1, e2) -> { return e1.compareTo(e2); });

বেনামী ক্লাস ব্যবহার করে ক্লাসিক উপায়:

int initialCapacity = 10;
PriorityQueue<T> pq = new PriorityQueue<>(initialCapacity, new Comparator<T> () {

    @Override
    public int compare(T e1, T e2) {
        return e1.compareTo(e2);
    }

});

বিপরীত ক্রমে বাছাই করতে, কেবল e1, e2 অদলবদল করুন।


3

আমি প্রিন্ট অর্ডার সম্পর্কেও ভাবছিলাম। এই ক্ষেত্রে বিবেচনা করুন, উদাহরণস্বরূপ:

অগ্রাধিকারের সারির জন্য:

PriorityQueue<String> pq3 = new PriorityQueue<String>();

এই কোড:

pq3.offer("a");
pq3.offer("A");

এর চেয়ে আলাদাভাবে মুদ্রণ করতে পারে:

String[] sa = {"a", "A"}; 
for(String s : sa)   
   pq3.offer(s);

আমি অন্য ফোরামে আলোচনার উত্তর পেয়েছি , যেখানে একজন ব্যবহারকারী বলেছিলেন, "অফার () / যুক্ত () পদ্ধতিগুলি কেবল সারিটিতে উপাদানটি সন্নিবেশ করায় you যদি আপনি কোন পূর্বাভাসযোগ্য আদেশ চান তবে আপনার পিক / পোল ব্যবহার করা উচিত যা মাথাটি ফিরে আসে should কিউ এর। "


3

ব্যবহারের বিকল্প হিসাবে Comparator, আপনি আপনার PriorityQueue প্রয়োগেComparable যে শ্রেণিটি ব্যবহার করছেন তাও থাকতে পারে (এবং একইভাবে compareToপদ্ধতিটি ওভাররাইড করে )।

দ্রষ্টব্য যে কেবলমাত্র সেই আদেশটি তার Comparableপরিবর্তে ব্যবহার করা সবচেয়ে ভাল Comparatorতবে যদি সেই আদেশটি অবজেক্টটির স্বজ্ঞাত অর্ডার হয় - উদাহরণস্বরূপ, যদি আপনার Personবয়সের সাহায্যে অবজেক্টগুলি বাছাই করার ক্ষেত্রে ব্যবহারের ক্ষেত্রে থাকে তবে কেবল তার Comparatorপরিবর্তে কেবল ব্যবহার করা ভাল।

import java.lang.Comparable;
import java.util.PriorityQueue;

class Test
{
    public static void main(String[] args)
    {
        PriorityQueue<MyClass> queue = new PriorityQueue<MyClass>();
        queue.add(new MyClass(2, "short"));
        queue.add(new MyClass(2, "very long indeed"));
        queue.add(new MyClass(1, "medium"));
        queue.add(new MyClass(1, "very long indeed"));
        queue.add(new MyClass(2, "medium"));
        queue.add(new MyClass(1, "short"));
        while (queue.size() != 0)
            System.out.println(queue.remove());
    }
}
class MyClass implements Comparable<MyClass>
{
    int sortFirst;
    String sortByLength;

    public MyClass(int sortFirst, String sortByLength)
    {
        this.sortFirst = sortFirst;
        this.sortByLength = sortByLength;
    }

    @Override
    public int compareTo(MyClass other)
    {
        if (sortFirst != other.sortFirst)
            return Integer.compare(sortFirst, other.sortFirst);
        else
            return Integer.compare(sortByLength.length(), other.sortByLength.length());
    }

    public String toString()
    {
        return sortFirst + ", " + sortByLength;
    }
}

আউটপুট:

1, short
1, medium
1, very long indeed
2, short
2, medium
2, very long indeed

1

অগ্রাধিকার সারিতে প্রতিটি উপাদানকে কিছু অগ্রাধিকার দেওয়া হয়েছে, সর্বোচ্চ অগ্রাধিকার সহ উপাদানটি সারিতে শীর্ষ সারিতে প্রদর্শিত হবে। এখন, এটি আপনার উপর নির্ভর করে যে আপনি কীভাবে প্রতিটি উপাদানকে অগ্রাধিকার অর্পণ করতে চান। আপনি যদি না করেন তবে জাভা এটি ডিফল্ট উপায়ে করবে। সর্বনিম্ন মান সহ উপাদানটিকে সর্বোচ্চ অগ্রাধিকার দেওয়া হয় এবং এইভাবে প্রথমে সারি থেকে সরানো হয়। যদি একই সর্বোচ্চ অগ্রাধিকার সহ বেশ কয়েকটি উপাদান থাকে তবে টাইটি নির্বিচারে ভেঙে যায়। আপনি কনস্ট্রাক্টরে তুলনামূলক ব্যবহার করে একটি অর্ডারও নির্দিষ্ট করতে পারেন PriorityQueue(initialCapacity, comparator)

উদাহরণ কোড:

PriorityQueue<String> queue1 = new PriorityQueue<>();
queue1.offer("Oklahoma");
queue1.offer("Indiana");
queue1.offer("Georgia");
queue1.offer("Texas");
System.out.println("Priority queue using Comparable:");
while (queue1.size() > 0) {
    System.out.print(queue1.remove() + " ");
}
PriorityQueue<String> queue2 = new PriorityQueue(4, Collections.reverseOrder());
queue2.offer("Oklahoma");
queue2.offer("Indiana");
queue2.offer("Georgia");
queue2.offer("Texas");
System.out.println("\nPriority queue using Comparator:");
while (queue2.size() > 0) {
    System.out.print(queue2.remove() + " ");
}

আউটপুট:

Priority queue using Comparable:
Georgia Indiana Oklahoma Texas 
Priority queue using Comparator:
Texas Oklahoma Indiana Georgia 

অন্যথায়, আপনি কাস্টম তুলককেও সংজ্ঞায়িত করতে পারেন:

import java.util.Comparator;

public class StringLengthComparator implements Comparator<String>
{
    @Override
    public int compare(String x, String y)
    {
        //Your Own Logic
    }
}

1

এখানে প্রাথমিক উদাহরণ যা আপনি প্রাথমিক শিক্ষার জন্য ব্যবহার করতে পারেন:

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;

public class PQExample {

    public static void main(String[] args) {
        //PriorityQueue with Comparator
        Queue<Customer> cpq = new PriorityQueue<>(7, idComp);
        addToQueue(cpq);
        pollFromQueue(cpq);
    }

    public static Comparator<Customer> idComp = new Comparator<Customer>(){

        @Override
        public int compare(Customer o1, Customer o2) {
            return (int) (o1.getId() - o2.getId());
        }

    };

    //utility method to add random data to Queue
    private static void addToQueue(Queue<Customer> cq){
        Random rand = new Random();
        for(int i=0;i<7;i++){
            int id = rand.nextInt(100);
            cq.add(new Customer(id, "KV"+id));
        }
    }


    private static void pollFromQueue(Queue<Customer> cq){
        while(true){
            Customer c = cq.poll();
            if(c == null) break;
            System.out.println("Customer Polled : "+c.getId() + " "+ c.getName());
        }
    }

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