"সেট" একটি গেট পদ্ধতি থাকা উচিত?


22

আসুন এই সি # ক্লাসটি করা যাক (এটি জাভাতে প্রায় একই হবে)

public class MyClass {
   public string A {get; set;}
   public string B {get; set;}

   public override bool Equals(object obj) {
        var item = obj as MyClass;

        if (item == null || this.A == null || item.A == null)
        {
            return false;
        }
        return this.A.equals(item.A);
   }

   public override int GetHashCode() {
        return A != null ? A.GetHashCode() : 0;
   }
}

আপনি দেখতে পাচ্ছেন, দুটি উদাহরণের সমতা কেবলমাত্র MyClassনির্ভর করে A। সুতরাং দুটি উদাহরণ থাকতে পারে যা সমান, তবে তাদের Bসম্পত্তিতে বিভিন্ন অংশের তথ্য রাখা ।

অনেক ভাষার একটি মান সংগ্রহের লাইব্রেরিতে (অবশ্যই সি # এবং জাভা সহ) রয়েছে একটি Set( HashSetসি # তে), যা একটি সংগ্রহ যা সমান দৃষ্টান্তগুলির প্রতিটি সেট থেকে কমপক্ষে একটি আইটেম ধরে রাখতে পারে।

কেউ আইটেম যুক্ত করতে, আইটেমগুলি সরাতে এবং সেটটিতে কোনও আইটেম রয়েছে কিনা তা পরীক্ষা করতে পারে। তবে সেট থেকে কোনও নির্দিষ্ট আইটেম পাওয়া কেন অসম্ভব?

HashSet<MyClass> mset = new HashSet<MyClass>();
mset.Add(new MyClass {A = "Hello", B = "Bye"});

//I can do this
if (mset.Contains(new MyClass {A = "Hello", B = "See you"})) {
    //something
}

//But I cannot do this, because Get does not exist!!!
MyClass item = mset.Get(new MyClass {A = "Hello", B = "See you"});
Console.WriteLine(item.B); //should print Bye

আমার আইটেমটি পুনরুদ্ধার করার একমাত্র উপায় হ'ল সম্পূর্ণ সংগ্রহটি পুনরাবৃত্তি করা এবং সম্যতার জন্য সমস্ত আইটেম পরীক্ষা করা। তবে এর O(n)বদলে সময় লাগে O(1)!

আমি এখনও পর্যন্ত কোনও সেট থেকে সমর্থন করে এমন কোনও ভাষা পাইনি। আমি জানি সমস্ত "সাধারণ" ভাষা (জাভা, সি #, পাইথন, স্কালা, হাস্কেল ...) একইভাবে ডিজাইন করা হয়েছে বলে মনে হচ্ছে: আপনি আইটেম যুক্ত করতে পারেন তবে আপনি সেগুলি পুনরুদ্ধার করতে পারবেন না। এই সমস্ত ভাষা সহজ এবং স্পষ্টতই দরকারী যে কোনও কিছুকে সমর্থন করে না তার কোনও যুক্তিসঙ্গত কারণ কি নেই? তারা ঠিক সব ভুল হতে পারে না, তাই না? এমন কোনও ভাষা রয়েছে যা এটি সমর্থন করে? কোনও সেট থেকে কোনও নির্দিষ্ট আইটেম পুনরুদ্ধার করা ভুল, তবে কেন?


কয়েকটি সম্পর্কিত এসও প্রশ্ন রয়েছে:

/programming/7283338/getting-an-element-from-a-set

/programming/7760364/how-to-retrieve-actual-item-from-hashsett


12
সি ++ std::setঅবজেক্ট পুনরুদ্ধারকে সমর্থন করে, সুতরাং সমস্ত "সাধারণ" ভাষা আপনার বর্ণনার মতো নয়।
মনিকা

17
আপনি দাবি যদি (এবং কোড) যে "MyClass দুই দৃষ্টান্ত সমতা একটি উপর নির্ভর করে কেবল" তারপর অন্য উদাহরণস্বরূপ আছে একই একটি মান এবং বিভিন্ন বি কার্যকরভাবে হয় "যে বিশেষ উদাহরণস্বরূপ", যেহেতু আপনি নিজেকে সংজ্ঞায়িত যে তারা সমান এবং বি মধ্যে পার্থক্য কোন ব্যাপার না; কনটেইনারটি সমান হওয়ায় অন্য উদাহরণটি "অনুমোদিত" করা হয়েছে।
পিটারিস

7
সত্য গল্প: জাভাতে, অনেকগুলি Set<E>বাস্তবায়ন কেবল Map<E,Boolean>অভ্যন্তরে।
কর্সিকা

10
ব্যক্তির সাথে কথা বলছেন : "হাই, আপনি এখানে একজন ব্যক্তিকে এখুনি আনতে পারেন"
ব্র্যাড থমাস

7
এটি a == bক্ষেত্রে প্রতিবিম্বিত ( সর্বদা সত্য) বিরতি দেয় this.A == nullif (item == null || this.A == null || item.A == null)পরীক্ষা সম্ভবত অর্ডার কৃত্রিমভাবে "উচ্চ মানের" কোড তৈরি করার জন্য, অনেক থেকে "ধরা" এবং চেক করুন। আমি এই ধরণের "overchecking" এবং কোড পর্যালোচনায় সমস্ত সময় অতিরিক্ত সংশোধন করে দেখছি।
usr

উত্তর:


66

এখানে সমস্যাটি এমন নয় যে HashSetকোনও Getপদ্ধতির অভাব নেই , এটি হ'ল আপনার কোডটি HashSetধরণের দৃষ্টিকোণ থেকে কোনও ধারণা রাখে না ।

এই Getপদ্ধতিটি কার্যকরভাবে, "আমাকে এই মানটিটি আনুন, দয়া করে", যার প্রতি .NET কাঠামোর লোকেরা বুদ্ধিমানভাবে উত্তর দেবে, "আহ? আপনার ইতিমধ্যে সেই মান আছে <confused face />"।

আপনি যদি আইটেমগুলি সঞ্চয় করতে চান এবং তার পরে অন্য কিছু ভিন্ন মানের মিলের ভিত্তিতে সেগুলি পুনরুদ্ধার করতে চান তবে আপনি যা করতে পারেন ততক্ষণ ব্যবহার Dictionary<String, MyClass>করুন:

var mset = new Dictionary<String, MyClass>();
mset.Add("Hello", new MyClass {A = "Hello", B = "Bye"});

var item = mset["Hello"];
Console.WriteLine(item.B); // will print Bye

এনক্যাপসুলেটেড শ্রেণীর কাছ থেকে সমতার তথ্য ফাঁস হয়। আমি যদি জড়িত সম্পত্তিগুলির সেটটি পরিবর্তন করতে চাই Equals, তবে আমাকে বাইরে কোড পরিবর্তন করতে হবে MyClass...

হ্যাঁ হ্যাঁ, তবে এটি MyClassহ'ল কমপক্ষে বিস্মিত হওয়ার নীতি (পওলা) নিয়ে মজাদার। সমতা কার্যকারিতা encapsulated সঙ্গে, এটি নিম্নলিখিত কোডটি বৈধ যে ধরে নেওয়া সম্পূর্ণ যুক্তিসঙ্গত:

HashSet<MyClass> mset = new HashSet<MyClass>();
mset.Add(new MyClass {A = "Hello", B = "Bye"});

if (mset.Contains(new MyClass {A = "Hello", B = "See you"})) 
{
    // this code is unreachable.
}

এটি প্রতিরোধের জন্য, MyClassএর সমতা বৈষম্য ফর্ম হিসাবে পরিষ্কারভাবে নথিভুক্ত করা প্রয়োজন। এটি সম্পন্ন করার পরে, এটি আর encapsulated এবং পরিবর্তিত হয় না যে সেই সাম্যতা কীভাবে কাজ করবে উন্মুক্ত / বদ্ধ নীতিটি ভঙ্গ করবে। তবে, এটি পরিবর্তন করা উচিত নয় এবং তাই Dictionary<String, MyClass>এই এই বিজোড় প্রয়োজনের জন্য একটি ভাল সমাধান।


2
@vojta, সেক্ষেত্রে Dictionary<MyClass, MyClass>এটি ব্যবহার করুন এটি ব্যবহার করে এমন কীগুলির উপর ভিত্তি করে মান আনবে MyClass.Equals
ডেভিড আরনো

8
আমি Dictionary<MyClass, MyClass>একটি যথাযথ সরবরাহ সরবরাহ ব্যবহার করব IEqualityComparer<MyClass>এবং সমতা সম্পর্কিত সম্পর্কটি এড়িয়ে যাব MyClassকেন তার MyClassসম্পর্কের উদাহরণগুলির তুলনায় এই সম্পর্ক সম্পর্কে জানতে হবে ?
কালেথ

16
@vojta এবং সেখানে মন্তব্য: " মেহ। সমান নয় এমন সমান বস্তুগুলি" সমান "হওয়ায় এখানে সমস্যাটি রয়েছে।" এমন একটি পদ্ধতির জন্য জিজ্ঞাসা করুন যাতে "আমাকে এই বস্তুর সাথে অভিন্ন বস্তুটি পান" এবং তারপরে প্রত্যাশিত কোনও অ-অভিন্ন বস্তুটি প্রত্যাবর্তনের জন্য উন্মাদ এবং রক্ষণাবেক্ষণের সমস্যার কারণ হতে পারে বলে মনে করা সহজ "is এটি প্রায়শই এসও-র সমস্যা: গুরুতর ত্রুটিযুক্ত উত্তরগুলি লোকদের দ্বারা উত্সাহিত হয় যারা তাদের ভাঙা কোডটিতে দ্রুত সমাধানের জন্য তাদের আকাঙ্ক্ষার বোঝায় না ...
ডেভিড আরনো

6
@ ডেভিড আর্নো: একধরনের অনিবার্য যদিও আমরা যতক্ষণ ভাষা সাম্যতা ও পরিচয়ের মধ্যে পার্থক্য ব্যবহার করে চলতে থাকি ;-) আপনি যদি সমান কিন্তু অভিন্ন নয় এমন বিষয়গুলিকে ক্যানোনিকালাইজ করতে চান তবে আপনার এমন একটি পদ্ধতি দরকার যা "আমাকে অভিন্ন না বলে" বলেছে এই বস্তুর প্রতি আপত্তি ", তবে" আমাকে এই বস্তুর সমান ক্যানোনিকাল অবজেক্টটি পান "। যে কেউ মনে করেন যে এই ভাষাগুলিতে হ্যাশসেট G
স্টিভ জেসোপ

4
এই উত্তরে অনেকগুলি কম্বল স্টেটমেন্ট রয়েছে ...reasonable to assume...। এই সমস্ত ক্ষেত্রে 99% ক্ষেত্রে সত্য হতে পারে তবে এখনও সেট থেকে কোনও আইটেম পুনরুদ্ধার করার ক্ষমতা কার্যকর হতে পারে। রিয়েল ওয়ার্ল্ড কোড সর্বদা পোলা ইত্যাদি নীতি অনুসরণ করতে পারে না। উদাহরণস্বরূপ, আপনি যদি স্ট্রিং কেস-সংবেদনশীলতার সাথে নকল করে থাকেন তবে আপনি "মাস্টার" আইটেমটি পেতে চাইতে পারেন। Dictionary<string, string>একটি workaround, কিন্তু এটি পারফেক্ট খরচ।
usr

24

আপনার কাছে ইতিমধ্যে সেটটিতে "থাকা" আইটেমটি রয়েছে - আপনি এটি কী হিসাবে পাস করেছেন।

"তবে এটিকে উদাহরণ হিসাবে বলা হয়নি যা আমি যুক্ত দিয়েছিলাম" - হ্যাঁ, তবে আপনি নির্দিষ্টভাবে দাবি করেছেন যে তারা সমান ছিল।

একটি Setএকটি একটি বিশেষ ক্ষেত্রে দেখা যায় Map| Dictionary, মান ধরণের হিসাবে শূন্যতা সহ (ভাল অব্যর্থ পদ্ধতিগুলি সংজ্ঞায়িত করা হয় না, তবে এটি কোনও বিষয় নয়)।

ডাটা স্ট্রাকচার আপনি খুঁজছেন একটি হল Dictionary<X, MyClass>যেখানে Xএকরকম MyClasses বাইরে হিসাবে পায়।

সি # অভিধানের প্রকারটি এই ক্ষেত্রে দুর্দান্ত, কারণ এটি আপনাকে কীগুলির জন্য একটি আইক্যুলিটি কম্পিউটার সরবরাহ করতে দেয়।

প্রদত্ত উদাহরণের জন্য আমার কাছে নিম্নলিখিতগুলি থাকবে:

public class MyClass {
   public string A {get; set;}
   public string B {get; set;}
}

public class MyClassEquivalentAs : IEqualityComparer<MyClass>{
   public override bool Equals(MyClass left, MyClass right) {
        if (Object.ReferenceEquals(left, null) && Object.ReferenceEquals(right, null))
        {
            return true;
        }
        else if (Object.ReferenceEquals(left, null) || Object.ReferenceEquals(right, null))
        {
            return false;
        }
        return left.A == right.A;
   }

   public override int GetHashCode(MyClass obj) {
        return obj?.A != null ? obj.A.GetHashCode() : 0;
   }
}

এইভাবে ব্যবহৃত:

var mset = new Dictionary<MyClass, MyClass>(new MyClassEquivalentAs());
var bye = new MyClass {A = "Hello", B = "Bye"};
var seeyou = new MyClass {A = "Hello", B = "See you"};
mset.Add(bye);

if (mset.Contains(seeyou)) {
    //something
}

MyClass item = mset[seeyou];
Console.WriteLine(item.B); // prints Bye

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

আজকে @ সুপারকার্যাট যা একটি দ্বারা অর্জন করা হয় Dictionary<String, String>
মাইকএফএই

@ মাইকফে: হ্যাঁ, তবে প্রতিটি স্ট্রিংয়ের রেফারেন্স দু'বার সংরক্ষণ করতে কিছুটা অনুপযুক্ত মনে হয় না।
সুপারক্যাট

2
@ সুপের্যাট যদি আপনি একটি অভিন্ন স্ট্রিংটি বোঝাতে চান তবে এটি কেবল ইন্টার্নিংয়ের স্ট্রিং। অন্তর্নির্মিত স্টাফ ব্যবহার করুন। যদি আপনি বোঝাতে চান কিছু প্রকার "আধ্যাত্মিক" উপস্থাপনা (যা সাধারণ কেস চেঞ্জিং কৌশল ইত্যাদি ব্যবহার করে অর্জন করা যায় না ), আপনার মনে হয় মূলত আপনার একটি সূচকের প্রয়োজন (অর্থে ডিবি শব্দটি ব্যবহার করেন)। আমি প্রতিটি "নন-ক্যানোনিকাল ফর্ম" একটি কী হিসাবে স্বীকৃত যা কোনও ক্যানোনিকাল ফর্মকে মানচিত্র হিসাবে দেখছি না। (আমি মনে করি এটি যদি "ক্যানোনিকাল" ফর্মটি স্ট্রিং না হয় তবে এটিও সমানভাবে প্রযোজ্য you're
jpmc26

1
কাস্টম Comparerএবং Dictionary<MyClass, MyClass>একটি ব্যবহারিক সমাধান। জাভাতে, একই TreeSetবা TreeMapআরও কাস্টম দ্বারা অর্জন করা যেতে পারে Comparator
মার্কাস কুল

19

আপনার সমস্যাটি হ'ল আপনার কাছে সমতার দুটি দ্বন্দ্বমূলক ধারণা রয়েছে:

  • প্রকৃত সাম্য যেখানে সমস্ত ক্ষেত্র সমান
  • সদস্যতা সমতা সেট করুন, যেখানে কেবল A সমান

যদি আপনি আপনার সেটে প্রকৃত সাম্যতা সম্পর্ক ব্যবহার করেন তবে সেট থেকে কোনও নির্দিষ্ট আইটেম পুনরুদ্ধারের সমস্যা দেখা দেয় না - কোনও বস্তু সেটে রয়েছে কিনা তা পরীক্ষা করতে আপনার ইতিমধ্যে সেই বস্তুটি রয়েছে। সুতরাং আপনি সঠিক সাম্যতার সম্পর্কটি ব্যবহার করছেন বলে ধরে নিয়ে কোনও সেট থেকে কোনও নির্দিষ্ট উদাহরণ পুনরুদ্ধার করা কখনই প্রয়োজন হয় না।

আমরা তর্ক করতে পারি যে একটি সেট একটি বিমূর্ত ডেটা টাইপ যা সংযোগ S contains xবা x is-element-of S"সম্পর্কের (" বৈশিষ্ট্যযুক্ত ফাংশন)) দ্বারা সংজ্ঞায়িত করা হয় । আপনি যদি অন্য অপারেশন চান, আপনি আসলে একটি সেট খুঁজছেন না।

কি বেশ প্রায়ই ঘটে - কিন্তু কি একটি সেট নয় - যে আমরা গ্রুপ স্বতন্ত্র মধ্যে সমস্ত বস্তু হল সমানতা শ্রেণীর । এই জাতীয় প্রতিটি শ্রেণীর বা উপসেটের অবজেক্টগুলি কেবল সমান, সমান নয়। আমরা সেই উপসেটের যে কোনও সদস্যের মাধ্যমে প্রতিটি সমতুল্য শ্রেণীর প্রতিনিধিত্ব করতে পারি এবং তারপরে প্রতিনিধিত্বকারী উপাদানটি পুনরুদ্ধার করা বাঞ্চনীয় হয়ে ওঠে। এটি সমতুল্য শ্রেণি থেকে প্রতিনিধি উপাদানটির ম্যাপিং হবে ।

সি # তে, একটি অভিধান একটি সুস্পষ্ট সাম্যের সম্পর্ক ব্যবহার করতে পারে, আমার ধারণা। অন্যথায়, এই জাতীয় সম্পর্ক দ্রুত র্যাপার ক্লাস লিখে প্রয়োগ করা যেতে পারে। pseudocode:

// The type you actually want to store
class MyClass { ... }

// A equivalence class of MyClass objects,
// with regards to a particular equivalence relation.
// This relation is implemented in EquivalenceClass.Equals()
class EquivalenceClass {
  public MyClass instance { get; }
  public override bool Equals(object o) { ... } // compare instance.A
  public override int GetHashCode() { ... } // hash instance.A
  public static EquivalenceClass of(MyClass o) { return new EquivalenceClass { instance = o }; }
}

// The set-like object mapping equivalence classes
// to a particular representing element.
class EquivalenceHashSet {
  private Dictionary<EquivalenceClass, MyClass> dict = ...;
  public void Add(MyClass o) { dict.Add(EquivalenceClass.of(o), o)}
  public bool Contains(MyClass o) { return dict.Contains(EquivalenceClass.of(o)); }
  public MyClass Get(MyClass o) { return dict.Get(EquivalenceClass.of(o)); }
}

"একটি সেট থেকে একটি নির্দিষ্ট উদাহরণ পুনরুদ্ধার করুন" আমার মনে হয় আপনি যদি "উদাহরণ" পরিবর্তন করে "সদস্য" হন তবে এটি আপনাকে আরও কী বোঝাতে চাইবে তা বোঝায়। একটি ছোট্ট পরামর্শ। =) +1
jpmc26

7

তবে সেট থেকে কোনও নির্দিষ্ট আইটেম পাওয়া কেন অসম্ভব?

কারণ যে সেট জন্য হয় না।

উদাহরণটি নতুন করে বলি।

"আমার কাছে একটি হ্যাশসেট রয়েছে যা আমি মাইক্লাসের অবজেক্টগুলিতে সঞ্চয় করতে চাই এবং আমি সম্পত্তি A ব্যবহার করে এটি পেতে সক্ষম হতে চাই যা বস্তুর সম্পত্তি A এর সমান হয়"।

যদি "হ্যাশসেট" কে "সংগ্রহ", "বস্তুগুলি" "মান" এবং "সম্পত্তি এ" এর সাথে "কী" দিয়ে প্রতিস্থাপন করা হয় তবে বাক্যটি হয়ে যায়:

"আমার কাছে একটি সংগ্রহ রয়েছে যা আমি মাইক্লাসের মানগুলিতে সঞ্চয় করতে চাই এবং আমি কী ব্যবহার করে তা অর্জন করতে সক্ষম হতে চাই যা বস্তুর কী সমান হয়"।

যা বর্ণনা করা হচ্ছে তা হচ্ছে একটি অভিধান। প্রকৃত প্রশ্নটি হ'ল "কেন আমি হ্যাশসেটকে অভিধান হিসাবে বিবেচনা করতে পারি না?"

উত্তরটি হ'ল তারা একই জিনিসটির জন্য ব্যবহৃত হয় না। সেটটি ব্যবহারের কারণ হ'ল এটির পৃথক সামগ্রীর স্বতন্ত্রতার গ্যারান্টি দেওয়া, অন্যথায় আপনি কেবল একটি তালিকা বা অ্যারে ব্যবহার করতে পারেন। প্রশ্নে বর্ণিত আচরণটি হ'ল ডিকশনারিটি কী। সমস্ত ভাষা ডিজাইনাররা স্ক্রু করেনি। তারা একটি গেট পদ্ধতি সরবরাহ করে না কারণ আপনার যদি বস্তু থাকে এবং এটি সেটে থাকে তবে সেগুলি সমতুল্য, যার অর্থ আপনি একটি সমমানের অবজেক্ট "পেয়ে" যাবেন। যুক্তি দেওয়া যে হ্যাশসেটটি এমনভাবে প্রয়োগ করা উচিত যাতে আপনি সমান হিসাবে সংজ্ঞায়িত নন-সমমানের অবজেক্টগুলিকে "পেতে" পারেন যখন ভাষাগুলি আপনাকে এমন ডেটা স্ট্রাকচার সরবরাহ করে যেগুলি আপনাকে এটি করতে দেয়।

ওওপি এবং সমতা সংক্রান্ত মন্তব্য / উত্তরগুলির একটি নোট। ম্যাপিংয়ের কীটি কোনও অভিধানে সঞ্চিত মূল্যের সম্পত্তি / সদস্য হওয়া ঠিক আছে। উদাহরণস্বরূপ: কী হিসাবে গাইড হিসাবে এবং সমান পদ্ধতির জন্য যে সম্পত্তি ব্যবহৃত হয় তা পুরোপুরি যুক্তিসঙ্গত। যা যুক্তিসঙ্গত নয় তা বাকি বৈশিষ্ট্যগুলির জন্য বিভিন্ন মান রয়েছে। আমি দেখতে পাচ্ছি যে আমি যদি সেই দিকে এগিয়ে যাচ্ছি তবে আমার বোধহয় আমার শ্রেণিবদ্ধের পুনর্বিবেচনা করা দরকার।


6

ওভাররাইড করার সাথে সাথেই আপনি আরও ভাল ওভাররাইড হ্যাশকোড। যত তাড়াতাড়ি আপনি এটি সম্পন্ন করবেন আপনার "উদাহরণস্বরূপ" আর কখনও অভ্যন্তরীণ অবস্থার পরিবর্তন করা উচিত নয়।

আপনি যদি সমান ওভাররাইড না করেন এবং হ্যাশকোড ভিএম অবজেক্টের পরিচয় সমতা নির্ধারণ করতে ব্যবহৃত হয়। আপনি যদি এই বস্তুকে কোনও সেটে রাখেন তবে আপনি এটি আবার খুঁজে পেতে সক্ষম হবেন।

সাম্য নির্ধারণের জন্য ব্যবহৃত একটি সামগ্রীর মান পরিবর্তন করা হ্যাশ ভিত্তিক কাঠামোগুলিতে এই অবজেক্টটির অন্রেসিবিলিটি হতে পারে।

সুতরাং একটি সেটার অন এ বিপজ্জনক।

এখন আপনার কাছে বি নেই যা সমতায় অংশ নেয় না। এখানে সমস্যা শব্দার্থগতভাবে প্রযুক্তিগতভাবে নয়। কারণ প্রযুক্তিগতভাবে বি পরিবর্তন করা সমতার সত্যের পক্ষে নিরপেক্ষ। শব্দার্থগতভাবে বিটিকে "সংস্করণ" পতাকার মতো কিছু হতে হবে।

এই পয়েন্ট টি:

আপনার কাছে দুটি সমতুল্য A সমান, তবে B নয়, আপনার কাছে একটি ধারণা রয়েছে যে এই বস্তুর মধ্যে একটি অপরটির চেয়ে নতুন। বি এর কোনও সংস্করণের তথ্য না থাকলে এই অনুমানটি আপনার অ্যালগরিদমে লুকানো থাকে যখন আপনি কোনও সেটটিতে এই বিষয়টিকে "ওভাররাইট / আপডেট" করার সিদ্ধান্ত নেন। এই উত্স কোড অবস্থান যেখানে এটি ঘটে তা সুস্পষ্ট নাও হতে পারে সুতরাং বিকাশকারীর কাছে X এবং বি এর সাথে পৃথক হওয়া অবজেক্ট এক্স এবং অবজেক্ট ওয়াইয়ের মধ্যকার সম্পর্ক সনাক্ত করতে খুব কঠিন সময় পাবে

বি এর সংস্করণ তথ্য থাকলে আপনি এই ধারনাটি প্রকাশ করেন যে পূর্বে কেবল কোড থেকে স্পষ্টতই প্রাপ্ত হয়েছিল। এখন আপনি দেখতে পাচ্ছেন, ওই অবজেক্ট Y হ'ল এক্সের একটি নতুন সংস্করণ is

নিজের সম্পর্কে চিন্তা করুন: আপনার পরিচয় আপনার পুরো জীবন থেকে যায়, কিছু বৈশিষ্ট্য পরিবর্তিত হতে পারে (যেমন আপনার চুলের রঙ ;-))। অবশ্যই আপনি ধরে নিতে পারেন যে আপনার যদি দুটি ছবি থাকে তবে একটি ধূসর চুলের সাথে বাদামী চুলের একটি, আপনার ছবি বাদামী চুলের সাথে আরও কম বয়সী হতে পারে। তবে আপনি কি চুলে রঙ করেছেন? সমস্যাটি হ'ল: আপনি হয়ত জানেন যে আপনি আপনার চুলগুলি রঙ করেছেন। অন্যরা করতে পারে? এটি একটি বৈধ প্রসঙ্গে রাখার জন্য আপনাকে সম্পত্তি বয়স (সংস্করণ) প্রবর্তন করতে হবে। তাহলে আপনি শব্দার্থগতভাবে স্পষ্ট এবং দ্ব্যর্থহীন।

"নতুন বস্তুর বিরুদ্ধে পুরানো প্রতিস্থাপন" লুকানো ক্রিয়াকলাপ এড়ানোর জন্য একটি সেটের গেট-পদ্ধতি থাকা উচিত নয়। আপনি যদি এর মতো আচরণ চান তবে আপনাকে পুরানো অবজেক্টটি সরিয়ে নতুন অবজেক্টটি যুক্ত করে এটি সুস্পষ্ট করতে হবে।

বিটিডাব্লু: আপনি যে অবজেক্টটি পেতে চান তার সমান হয় এমন কোনও বস্তু পাস করলে এর অর্থ কী হওয়া উচিত? এর কোনো মানে নাই. আপনার শব্দার্থবিজ্ঞান পরিষ্কার রাখুন এবং প্রযুক্তিগতভাবে কেউ আপনাকে বাধা দেবে না যদিও এটি করবেন না।


7
"আপনি ওভাররাইড করার সাথে সাথেই আপনি আরও ভাল ওভাররাইড হ্যাশকোডের সমান হবেন। এই বিবৃতি এখনই +100 মূল্য।
ডেভিড আরনো

পরিবর্তনীয় রাষ্ট্রের উপর নির্ভর করে সমতা এবং হ্যাশকোডের বিপদগুলি নির্দেশ করার জন্য +1
হাল্ক

3

বিশেষত জাভাতে, HashSetপ্রথমে HashMapযাইহোক যাইহোক ব্যবহার করে প্রয়োগ করা হয়েছিল , এবং কেবল মানটিকে উপেক্ষা করে। সুতরাং প্রাথমিক নকশাটি কোনও গেট মেথড সরবরাহের ক্ষেত্রে কোনও সুবিধা প্রত্যাশা করে না HashSet। আপনি যদি সমান সমান বিভিন্ন অবজেক্টগুলির মধ্যে একটি প্রচলিত মান সংরক্ষণ এবং পুনরুদ্ধার করতে চান তবে আপনি কেবল HashMapনিজের ব্যবহার করুন।

আমি এ জাতীয় বাস্তবায়ন সংক্রান্ত বিশদটি দিয়ে আপ টু ডেট রাখিনি, সুতরাং আমি এই যুক্তিটি জাভাতে এখনও পুরোপুরি প্রয়োগ হয় কিনা, সি # তে ছেড়ে দেওয়া যাক না, তবে HashSetকোনও অবস্থাতেই HashMapএটির চেয়ে কম মেমরি ব্যবহার করার জন্য পুনরায় প্রয়োগ করা হলেও আমি তা বলতে পারি না it Setইন্টারফেসে একটি নতুন পদ্ধতি যুক্ত করার জন্য একটি ব্রেকিং পরিবর্তন হবে । সুতরাং এটি লাভের জন্য যথেষ্ট পরিমাণে বেদনা যা সবাই রাখার যোগ্য হিসাবে দেখেনি।


ঠিক আছে, জাভাতে এটি একটি অ-ব্রেকিং উপায়ে করার জন্য একটি সরবরাহ সরবরাহ করা সম্ভব হতে পারে default। এটি কেবল মারাত্মকভাবে কার্যকর পরিবর্তন বলে মনে হচ্ছে না।
হাল্ক

@ হাল্ক: আমি ভুল হতে পারি, তবে আমি মনে করি যে কোনও ডিফল্ট প্রয়োগ কার্যকরভাবে অদক্ষ হয়ে উঠবে, যেহেতু প্রশ্নকর্তা বলেছেন, "আমার আইটেমটি পুনরুদ্ধার করার একমাত্র উপায় পুরো সংগ্রহটি পুনরুদ্ধার করা এবং সাম্যতার জন্য সমস্ত আইটেম পরীক্ষা করা"। সুতরাং ভাল পয়েন্ট, আপনি এটি একটি পশ্চাদপটে সামঞ্জস্যপূর্ণ উপায়ে করতে পারেন, তবে একটি গেটচা যুক্ত করে যে ফলস্বরূপ প্রাপ্ত ফাংশনটি কেবল O(n)তুলনামূলকভাবে চালানোর গ্যারান্টি দেয় এমনকি হ্যাশ ফাংশনটি ভাল বিতরণ দিচ্ছে। তারপরে এর প্রয়োগগুলি Setইন্টারফেসে ডিফল্ট বাস্তবায়ন ওভাররাইড সহ HashSet, আরও ভাল গ্যারান্টি দিতে পারে।
স্টিভ জেসোপ

সম্মত - আমি মনে করি না এটি একটি ভাল ধারণা হবে। সেখানে আচরণ যদিও এই ধরনের precedences হবে - List.get (int- INDEX) বা - একটি ডিফল্ট বাস্তবায়ন সম্প্রতি যোগ বাছাই List.sort । ইন্টারফেসের মাধ্যমে সর্বাধিক জটিলতার গ্যারান্টি সরবরাহ করা হয় তবে কিছু বাস্তবায়ন অন্যের চেয়ে অনেক বেশি ভাল করতে পারে।
হাল্ক

2

একটি প্রধান ভাষা রয়েছে যার সেটে আপনার পছন্দসই সম্পত্তি রয়েছে।

সি ++ এ, std::setএকটি অর্ডার করা সেট। এটিতে এমন একটি .findপদ্ধতি রয়েছে যা অর্ডারিং অপারেটর <বা বাইনারি bool(T,T)ফাংশন সরবরাহ করে তার উপর ভিত্তি করে উপাদানটির সন্ধান করে । আপনি নিজেরাই পেতে চান অপারেশন বাস্তবায়ন করতে আপনি ব্যবহার করতে পারেন।

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

এটি একটি দক্ষ অনুমতি দেয়:

std::set< std::string, my_string_compare > strings;
strings.find( 7 );

যেখানে my_string_compareপ্রথমে পূর্ণসংখ্যাকে একটি স্ট্রিংয়ে রূপান্তর না করে (সম্ভাব্য ব্যয়ে) কীভাবে পূর্ণসংখ্যা এবং স্ট্রিংগুলি অর্ডার করতে হয় তা বোঝে।

জন্য unordered_set(সি ++ এর হ্যাশ সেট থাকে), কোন সমতুল্য স্বচ্ছ পতাকা (এখনও) হয়। আপনাকে অবশ্যই Tএকটি unordered_set<T>.findপদ্ধতিতে পাস করতে হবে । এটি যুক্ত করা যেতে পারে তবে হ্যাশগুলির প্রয়োজন হয় ==এবং একটি হ্যাশার, অর্ডার করা সেটগুলির বিপরীতে যা কেবল একটি অর্ডারিংয়ের প্রয়োজন।

সাধারণ প্যাটার্নটি হ'ল ধারকটি অনুসন্ধান করবে, তারপরে ধারকটির মধ্যে সেই উপাদানটিকে একটি "পুনরাবৃত্তিকারী" দেবে। কোন বিন্দুতে আপনি সেটটির মধ্যে উপাদানটি পেতে পারেন, বা এটি মুছতে পারেন ইত্যাদি

সংক্ষেপে, সমস্ত ভাষার স্ট্যান্ডার্ড পাত্রে আপনার বর্ণিত ত্রুটিগুলি নেই। সি ++ স্ট্যান্ডার্ড লাইব্রেরির আইট্রেটর-ভিত্তিক কনটেইনারগুলি নেই এবং আপনার বর্ণিত অন্যান্য ভাষাগুলির মধ্যে কমপক্ষে কয়েকটি ধারক উপস্থিত ছিল এবং আপনি যেভাবে বর্ণনা করেছেন তার থেকেও আরও দক্ষতার সাথে কাজ করার ক্ষমতা যুক্ত করা হয়েছে। আপনার নকশা, বা সেই অপারেশনটি চাওয়াতে কোনও ভুল নেই; আপনি যে সেটগুলি ব্যবহার করছেন সেগুলির ডিজাইনাররা সেই ইন্টারফেসটি সরবরাহ করেনি।

সি ++ স্ট্যান্ডার্ড পাত্রে যেখানে সমান হ্যান্ড-রোলড সি কোডের নিম্ন-স্তরের ক্রিয়াকলাপ পরিষ্কারভাবে মোড়ানোর জন্য ডিজাইন করা হয়েছিল, এটি কীভাবে আপনি সমাবেশে দক্ষতার সাথে লিখতে পারেন তা মেলানোর জন্য ডিজাইন করা হয়েছিল। এর পুনরুক্তিগুলি সি-স্টাইল পয়েন্টারগুলির বিমূর্ততা। আপনি যে ভাষাগুলির উল্লেখ করেছেন সেগুলি সমস্ত ধারণা হিসাবে পয়েন্টার থেকে দূরে সরে গেছে, তাই তারা পুনরাবৃত্তি বিমূর্তি ব্যবহার করে নি।

এটি সম্ভবত সম্ভব যে সি ++ এর ত্রুটি নেই এটি ডিজাইনের একটি দুর্ঘটনা। পুনরাবৃত্তকেন্দ্রিক পাথের অর্থ হ'ল কোনও সংযুক্ত পাত্রে কোনও আইটেমটির সাথে ইন্টারেক্ট করার জন্য আপনি প্রথমে উপাদানটির একটি পুনরুক্তি পেতে পারেন, তারপরে আপনি ধারকটিতে প্রবেশের বিষয়ে কথা বলতে সেই পুনরাবৃত্তিকে ব্যবহার করেন।

ব্যয়টি হ'ল এখানে পুনরাবৃত্তি অবৈধকরণের নিয়ম রয়েছে যা আপনার ট্র্যাক করতে হবে এবং কিছু ক্রিয়াকলাপের জন্য একটিটির পরিবর্তে ২ টি পদক্ষেপের প্রয়োজন হয় (যা ক্লায়েন্ট কোডটি নয়েজ করে তোলে)। সুবিধাটি হ'ল এপিআই ডিজাইনাররা মূলত মনে রাখার চেয়ে শক্তিশালী বিমূর্ততা আরও উন্নত ব্যবহারের অনুমতি দেয়।

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