নেট। আইইইকুএলসিটি কম্পিউটার> <T> এ গেটহ্যাশকোডের ভূমিকা কী?


142

আমি ইন্টারফেস আইকোয়ালিটি কম্পিউটারের গেটহ্যাশকোড পদ্ধতির ভূমিকা বোঝার চেষ্টা করছি।

নিম্নলিখিত উদাহরণটি এমএসডিএন থেকে নেওয়া:

using System;
using System.Collections.Generic;
class Example {
    static void Main() {
        try {

            BoxEqualityComparer boxEqC = new BoxEqualityComparer();

            Dictionary<Box, String> boxes = new Dictionary<Box,
                                                string>(boxEqC);

            Box redBox = new Box(4, 3, 4);
            Box blueBox = new Box(4, 3, 4);

            boxes.Add(redBox, "red");
            boxes.Add(blueBox, "blue");

            Console.WriteLine(redBox.GetHashCode());
            Console.WriteLine(blueBox.GetHashCode());
        }
        catch (ArgumentException argEx) {

            Console.WriteLine(argEx.Message);
        }
    }
}

public class Box {
    public Box(int h, int l, int w) {
        this.Height = h;
        this.Length = l;
        this.Width = w;
    }
    public int Height { get; set; }
    public int Length { get; set; }
    public int Width { get; set; }
}

class BoxEqualityComparer : IEqualityComparer<Box> {

    public bool Equals(Box b1, Box b2) {
        if (b1.Height == b2.Height & b1.Length == b2.Length
                            & b1.Width == b2.Width) {
            return true;
        }
        else {
            return false;
        }
    }

    public int GetHashCode(Box bx) {
        int hCode = bx.Height ^ bx.Length ^ bx.Width;
        return hCode.GetHashCode();
    }
}

দুটি বক্স অবজেক্টের তুলনায় সমান পদ্ধতির প্রয়োগটি কি পর্যাপ্ত হওয়া উচিত নয়? এটিই আমরা ফ্রেমওয়ার্কটি অবজেক্টগুলির তুলনা করতে ব্যবহৃত নিয়মটি বলি। গেটহ্যাশকোডের প্রয়োজনীয়তা কেন?

ধন্যবাদ।

লুসিয়ান


একটি পড়ুন: en.wikedia.org/wiki/Hash_table তারপর দেখুন আপনি getHashCode এর উদ্দেশ্যটি আরও ভালভাবে বুঝতে পারছেন কিনা।
ব্যয়কারী

1
এই দুর্দান্ত উত্তরটি দেখুন: stackoverflow.com/a/3719802/136967
মিখাইল

উত্তর:


200

প্রথমে কিছুটা পটভূমি ...

.NET এর প্রতিটি বস্তুর একটি সমান পদ্ধতি এবং একটি getHashCode পদ্ধতি রয়েছে।

সমান পদ্ধতিটি একটি বস্তুকে অন্য বস্তুর সাথে তুলনা করতে ব্যবহৃত হয় - এটি দেখার জন্য যে দুটি বস্তু সমান কিনা।

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

একটি অভিধান হ'ল একটি দুর্দান্ত ডেটা কাঠামো যা যোগ / অপসারণ / ক্রিয়াকলাপ ক্রিয়াকলাপের জন্য ধ্রুবক ব্যয় (আরও কম) এর বিনিময়ে উচ্চতর মেমরির পদচিহ্নের ব্যবসা করে। যদিও এটি পুনরাবৃত্তি করার জন্য একটি দুর্বল পছন্দ is অভ্যন্তরীণভাবে, একটি অভিধানে বালতিগুলির একটি অ্যারে থাকে, যেখানে মানগুলি সংরক্ষণ করা যায়। আপনি যখন কোনও অভিধানে একটি কী এবং মান যুক্ত করেন, তখন কী-তে getHashCode পদ্ধতিটি কল করা হয়। ফিরে আসা হ্যাশকোডটি বালতিতে কী / মান জোড় সংরক্ষণ করা উচিত তার সূচি নির্ধারণ করতে ব্যবহৃত হয়।

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

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

উভয় পদ্ধতি কেন প্রয়োজনীয় তা ব্যাখ্যা করার জন্য, এই উদাহরণটি বিবেচনা করুন:

BoxEqualityComparer boxEqC = new BoxEqualityComparer(); 

Dictionary<Box, String> boxes = new Dictionary<Box, string>(boxEqC); 

Box redBox = new Box(100, 100, 25);
Box blueBox = new Box(1000, 1000, 25);

boxes.Add(redBox, "red"); 
boxes.Add(blueBox, "blue"); 

আপনার উদাহরণে BoxEqualityComparer.GetHashCode পদ্ধতি ব্যবহার করে, এই উভয় বাক্সে একই হ্যাশকোড রয়েছে - 100 ^ 100 ^ 25 = 1000 ^ 1000 ^ 25 = 25 - যদিও তারা স্পষ্টভাবে একই বস্তু নয়। এক্ষেত্রে তারা একই হ্যাশকোড হওয়ার কারণ হ'ল আপনি ^ (বিটওয়াইজ এক্সক্লুসিভ-ওআর) অপারেটরটি ব্যবহার করছেন তাই ১০০ ^ ১০০ বাতিল করে শূন্য ছেড়ে, যেমন 1000 ^ 1000 করে does যখন দুটি পৃথক বস্তুর একই কী থাকে, তখন আমরা একে সংঘর্ষ বলি।

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

আপনি যে উদাহরণটি পোস্ট করেছেন তাতে দুটি বাক্স সমান, সুতরাং সমান পদ্ধতিটি সত্য ফিরে আসে। এই ক্ষেত্রে অভিধানে দুটি অভিন্ন কী রয়েছে, সুতরাং এটি একটি ব্যতিক্রম ছুঁড়ে।

TLDR

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


4
তাদের জন্য, ope-পরিচালকটি কী তা ভাবছেন, এটি হ'ল বিটওয়াইজ এক্সক্লুসিভ-ওআর অপারেটর, দেখুন msdn.microsoft.com/en-us/library/zkacc7k1.aspx
আর শেরুর্স

2
কেবল এটিকে স্পষ্টভাবে উল্লেখ করার জন্য: ( msdn.microsoft.com/en-us/library/ms132155.aspx ) ইমপ্লিমেন্টারদের নোটগুলি বাস্তবায়নগুলি নিশ্চিত করতে প্রয়োজনীয় যে যদি সমান পদ্ধতি দুটি এবং দুটি বস্তুর জন্য সত্য ফিরে আসে তবে মানটি ফিরে আসবে গেটহ্যাশকোড পদ্ধতি অনুসারে এক্স এর জন্য y এর জন্য প্রাপ্ত মানের সমান হতে হবে।
দিয়েগো ফ্রেহনার

2
@ ডিগো ফ্রেহনার - আপনি ঠিক বলেছেন। অন্য জিনিস যা লোককে ট্রিপ করতে পারে তা হ'ল বস্তুটি সংশোধন করা হলে গেটহ্যাশকোড পদ্ধতির মান আলাদা হওয়া উচিত নয়। সুতরাং গেটহ্যাশকোড যে বস্তুর উপর নির্ভর করে তার মধ্যে ক্ষেত্রগুলি কেবল পঠনযোগ্য (অপরিবর্তনীয়) হওয়া উচিত। : একটি ব্যাখ্যা এখানে আছে stackoverflow.com/a/4868940/469701
sheikhjabootie

1
@ অ্যাসেন্ট্রিক: সামঞ্জস্যকে প্রভাবিত করে এমন কোনও ফ্যাশনে রূপান্তর না করা যদি না কোনও অবজেক্টের হ্যাশ কোড পরিবর্তন করা উচিত না। সাম্যকে প্রভাবিত করতে যেমন কোনও শ্রেণিকে যদি এমন ফ্যাশনে রূপান্তরিত করা যায় তবে কোড অভিধানে থাকতে পারে এমন কোনও উদাহরণ যা কোডের সাথে প্রকাশিত হতে পারে সেটিকে অভিধানে সংরক্ষণ করা উচিত। যদি আইটেমটি সংরক্ষণ করে সেই কোডটি যদি সেই নিয়ম মেনে চলে, একটি হ্যাশ কোড থাকা যা মিউটিটেবলের অবস্থা প্রতিফলিত করে তা কার্যকর হতে পারে। এটি খুব খারাপ N NET রাষ্ট্রের সাম্যতা এবং সমতুল্যতার চেয়ে আলাদাভাবে পার্থক্য করে না, কারণ উভয়ই কার্যকর ধারণা।
সুপারক্যাট

3
@ অ্যাসেন্ট্রিক: হ্যাশ-টেবিল সম্বোধনের জন্য হ্যাশ কোড ব্যবহারের বাইরেও, একটি হ্যাশ কোডের পিছনের মৌলিক ধারণাটি হ'ল যে দুটি বস্তুর বিভিন্ন হ্যাশ কোড রয়েছে তা জ্ঞানটি বোঝায় যে তারা অসম এবং তাদের তুলনা করার দরকার নেই। একটি ছদ্মবেশ হিসাবে, অনেক অবজেক্টের হ্যাশ কোড একটি প্রদত্ত অবজেক্টের হ্যাশ কোডের সাথে মেলে না এমন জ্ঞান বোঝায় যে এগুলির কোনওটিই বস্তুর সমান নয়। সম্বোধনের জন্য একটি হ্যাশ কোড ব্যবহার করা মূলত এমন বস্তুগুলিকে উপেক্ষা করার একটি উপায় যাগুলির বিভিন্ন হ্যাশ কোড রয়েছে।
ক্যাট

9

গেটহ্যাশকোড অভিধান সংকলনে ব্যবহৃত হয় এবং এটি এতে বস্তু সংরক্ষণের জন্য হ্যাশ তৈরি করে। আইক্যালিটিকম্পারার এবং গেটহ্যাশকোড http://dotnetperls.com/iequalitycomparer কেন এবং কীভাবে ব্যবহার করবেন তা এখানে একটি সুন্দর নিবন্ধ


4
আরও: আপনার যদি সমান তুলনা করার দরকার হয় তবে এটি প্রশংসনীয় হবে, তবে আপনার অভিধান থেকে উপাদান পাওয়ার দরকার হলে হ্যাশ দিয়ে এটি করা সহজ, সমান ব্যবহার করে নয় ।
অ্যাশ

5

যদিও এটির জন্য Dictionary<TKey,TValue>এটির GetValueঅনুরূপ পদ্ধতিগুলির Equalsজন্য প্রতিটি সঞ্চিত কীতে এটি চাওয়া হওয়াটির সাথে মিলছে কিনা তা দেখতে কল করা সম্ভব হবে , এটি খুব ধীর হবে। পরিবর্তে, অনেকগুলি হ্যাশ-ভিত্তিক সংগ্রহগুলির মতো, এটি GetHashCodeবেশিরভাগ মিল না করা মানগুলি বিবেচনা থেকে দ্রুত বাদ দেওয়ার উপর নির্ভর করে । যদি GetHashCodeকোন আইটেমটির জন্য চাওয়া হচ্ছে 42 টি ফলন হয়েছে এবং সংগ্রহে রয়েছে 53,917 টি আইটেম, তবে আইটেমের GetHashCode53,914 এ কল করে 42 টি ব্যতীত অন্য কোনও মূল্য পাওয়া যায়, তবে কেবল 3 টি আইটেম অনুসন্ধান করা বিষয়গুলির সাথে তুলনা করতে হবে। অন্যান্য 53,914 নিরাপদে উপেক্ষা করা হতে পারে।

ক এর GetHashCodeসাথে অন্তর্ভুক্ত হওয়ার কারণটি হ'ল IEqualityComparer<T>কোনও অভিধানের গ্রাহক সমান বস্তু হিসাবে বিবেচনা করতে চান যা সাধারণত একে অপরকে সমান হিসাবে বিবেচনা করে না । সর্বাধিক সাধারণ উদাহরণটি এমন একজন কলার হবে যা কী হিসাবে স্ট্রিংগুলি ব্যবহার করতে চায় তবে কেস-সংবেদনশীল তুলনা ব্যবহার করে। সেই কাজটি দক্ষতার সাথে করার জন্য, অভিধানটিতে কিছু ফর্ম হ্যাশ ফাংশন থাকা দরকার যা "ফক্স" এবং "ফক্স" এর জন্য একই মান অর্জন করবে, তবে আশা করি "বাক্স" বা "জেব্রা" এর জন্য অন্য কিছু পাওয়া যায়। যেহেতু GetHashCodeঅন্তর্নির্মিত পদ্ধতিটি Stringসেভাবে কাজ করে না, অভিধানে অন্য কোথাও থেকে এই জাতীয় পদ্ধতি নেওয়া দরকার,IEqualityComparer<T>Equals "ফক্স" এবং "ফক্স" একে অপরের সাথে অভিন্ন হিসাবে বিবেচিত পদ্ধতি, তবে "বাক্স" বা "জেব্রা" নয়।


সঠিক এবং প্রশ্নের জবাব উত্তর! গেটহ্যাশকোড () কে প্রশ্নযুক্ত বস্তুর জন্য সমান () পরিপূরক করতে হবে।
সুমিত

@ সুমিত: বালতি সম্পর্কে হ্যাশিং টক নিয়ে অনেক আলোচনা, তবে আমি মনে করি এটি বাদ দেওয়ার কথা ভাবা আরও কার্যকর। তুলনাগুলি ব্যয়বহুল হলে, বালিশে সংগঠিত নয় এমন সংগ্রহগুলি ব্যবহার করার পরেও হ্যাশিং উপকারের প্রস্তাব দিতে পারে।
সুপারক্যাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.