কিভাবে একটি হ্যাশ টেবিল কাজ করে?


494

আমি কীভাবে হ্যাশ টেবিলটি কাজ করে তার ব্যাখ্যা খুঁজছি - আমার মতো সরলতার জন্য সরল ইংরেজিতে!

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

প্রক্রিয়াটি কি কেউ ব্যাখ্যা করতে পারে?

সম্পাদনা: আমি কীভাবে হ্যাশ কোড গণনা করা হয় তা সম্পর্কে বিশেষত জিজ্ঞাসা করছি না, তবে হ্যাশ টেবিল কীভাবে কাজ করে তার একটি সাধারণ ওভারভিউ।


4
সম্প্রতি, আমি এই ( en.algoritmy.net/article/50101/Hash-table ) নিবন্ধটি লিখেছি হ্যাশ টেবিল এবং তাদের কৌশলগুলি (পৃথক চেইনিং, লিনিয়ার প্রোব, ডাবল হ্যাশিং) সহ অ্যাকসেন্ট সহ, বিভিন্ন উপায়ে, কীভাবে ডেটা সঞ্চয় এবং অনুসন্ধান করা যায় তা বর্ণনা করে )
পুরুষজপাভুক

1
আপনি কোনও অ্যারের বর্ধিত সংস্করণ হিসাবে হ্যাশ টেবিলটি ভাবতে পারেন, এটি কেবল একটানা সংখ্যার কীগুলির মধ্যে সীমাবদ্ধ নয়।
ব্যবহারকারী 253751

উত্তর:


913

সাধারণ ব্যক্তির শর্তাবলী এখানে একটি ব্যাখ্যা।

ধরে নেওয়া যাক আপনি বইয়ের সাথে একটি লাইব্রেরি পূরণ করতে চান এবং কেবল সেখানে স্টাফই করেন না, তবে আপনার যখন প্রয়োজন হবে তখন সহজেই এগুলি আবার সন্ধান করতে সক্ষম হতে চান।

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

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

আপনি এমন কিছু চান যা বইয়ের শিরোনাম সহ, আপনাকে একবারে সঠিক স্থান দিতে পারে, তাই আপনাকে যা করতে হবে তা হ'ল ডান শেল্ফটিতে সরে যাওয়া এবং বইটি তুলে নেওয়া।

তবে কীভাবে তা করা যায়? ঠিক আছে, আপনি যখন গ্রন্থাগারটি পূরণ করেন তখন অনেকটা পূর্বানুমতি দিয়ে এবং যখন আপনি লাইব্রেরিটি পূরণ করেন তখন প্রচুর কাজ।

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

এই প্রোগ্রামটির সৌন্দর্য হ'ল পরবর্তীতে, কোনও ব্যক্তি যখন বইটি পড়তে ফিরে আসে, আপনি প্রোগ্রামের মাধ্যমে আবার শিরোনামটি খাওয়ান, এবং আপনাকে একইভাবে দেওয়া শেল্ফ নম্বর এবং স্লট নম্বরটি ফিরে পেয়েছিলেন, এবং এটি হ'ল বই যেখানে অবস্থিত।

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

সরলতার জন্য, আসুন আমরা বলি যে এটি প্রতিটি অক্ষর এবং চিহ্নকে কেবল একটি সংখ্যায় রূপান্তর করে এবং সেগুলি সবগুলি যোগ করে। বাস্তবে, এটি এর চেয়ে অনেক জটিল, তবে আসুন আপাতত এটিকে ছেড়ে দিন।

এই জাতীয় অ্যালগরিদমের সৌন্দর্য হ'ল আপনি যদি বার বার একই ইনপুটটি খাওয়াতে থাকেন তবে এটি প্রতিবার একই সংখ্যায় থুতু ফেলে রাখবে।

ঠিক আছে, সুতরাং এটি মূলত হ্যাশ টেবিলটি কীভাবে কাজ করে।

প্রযুক্তিগত জিনিস অনুসরণ করা হয়।

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

তাই আমরা কি কাজ করতে পারি? আমরা মডুলাস ক্যালকুলেশন নামে কিছু ব্যবহার করি, যা মূলত বলা হয় যে আপনি যদি নিজের সংখ্যাটি (যেমন এক বিলিয়ন সংখ্যা) গণনা করেছিলেন তবে আপনি যদি আরও ছোট পরিসরের ভিতরে থাকতে চান, প্রতিবার যখন আপনি সেই ছোট পরিসরের সীমাটি আঘাত করেন তখন আপনি শুরু করেছিলেন 0, তবে আপনি যে বড় ক্রমটি এসেছেন সে সম্পর্কে আপনাকে কতদূর ট্র্যাক করতে হবে।

বলুন যে হ্যাশ অ্যালগরিদমের আউটপুট 0 থেকে 20 এর মধ্যে রয়েছে এবং আপনি একটি নির্দিষ্ট শিরোনাম থেকে 17 মান পাবেন। লাইব্রেরির আকার যদি মাত্র 7 টি বই হয় তবে আপনি 1, 2, 3, 4, 5, 6 গণনা করুন এবং আপনি 7 এ পৌঁছে গেলে আপনি 0 এ ফিরে যান start যেহেতু আমাদের 17 বার গণনা করা দরকার, আমাদের কাছে 1 টি রয়েছে, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, এবং চূড়ান্ত সংখ্যা 3।

অবশ্যই মডুলাস গণনা সেভাবে করা হয় না, এটি বিভাগ এবং একটি বাকী অংশ দিয়ে সম্পন্ন হয়। 17 কে 7 দ্বারা ভাগ করার বাকি অংশটি 3 (7 টি 14 বার 14 এ 2 বার হয় এবং 17 এবং 14 এর মধ্যে পার্থক্য 3)।

এইভাবে, আপনি বইটি স্লট 3 নম্বরে রেখেছেন।

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

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

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

আমি আশা করি বালতি এবং ফাংশনগুলির তুলনায় এই ব্যাখ্যাটি পৃথিবীতে কিছুটা নিচে ছিল :)


এত বড় ব্যাখ্যার জন্য ধন্যবাদ। আপনি কী জানেন যে আমি এটি কীভাবে 4.x। নেট ফ্রেমওয়ার্কে কার্যকর করা হয়েছে সে সম্পর্কিত আরও প্রযুক্তিগত বিশদ জানতে পারি?
জনি_ডি

না, এটি কেবল একটি সংখ্যা। আপনি কেবল প্রতিটি শেল্ফ এবং স্লট 0 বা 1 থেকে শুরু করে এবং সেই শেল্ফের প্রতিটি স্লটের জন্য 1 দ্বারা বাড়িয়েছিলেন, তারপরে পরবর্তী শেল্ফটিতে নম্বরটি চালিয়ে যান।
লাসে ভি কার্লসেন

2
'টেবিলের আরও একটি দাগ পাওয়ার জন্য ডেটা চালিয়ে অন্য কোনও গণনায় ডেটা চালানো সহ বিভিন্ন সংঘর্ষ পরিচালনার পদ্ধতি বিদ্যমান' - অন্য একটি গণনা বলতে কী বোঝ? এটা কি আর একটি অ্যালগোরিদম? ঠিক আছে, সুতরাং ধরুন আমরা অন্য একটি অ্যালগরিদম ব্যবহার করি যা বইয়ের নামের উপর ভিত্তি করে একটি পৃথক নম্বর আউটপুট করে। তারপরে, যদি আমি সেই বইটি খুঁজে পাই, তবে আমি কীভাবে জানব যে কোন অ্যালগরিদমটি ব্যবহার করতে হবে? আমি প্রথম অ্যালগরিদম, দ্বিতীয় অ্যালগরিদম এবং আরও কিছুক্ষণ ব্যবহার করব, যতক্ষণ না আমি যে বইটির সন্ধান করছি সেই বইটি খুঁজে পাচ্ছি?
ব্যবহারকারী 107986

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

3
@ কাইলডিলেনি: আপনার মন্তব্য সম্পর্কে অবহিত করতে "@ টনি" জিনিসটির প্রয়োজন। মনে হচ্ছে আপনি শৃঙ্খলাবদ্ধতা নিয়ে ভাবছেন: বলুন আমাদের কাছে তিনটি মান নোড A{ptrA, valueA}, B{ptrB, valueB}, C{ptrC, valueC}এবং তিনটি বালতিযুক্ত একটি হ্যাশ টেবিল রয়েছে [ptr1, ptr2, ptr3]। Whenোকানোর সময় সংঘর্ষ রয়েছে কিনা তা বিবেচনা না করেই, মেমরির ব্যবহার স্থির করা আছে। আপনার কোনও সংঘর্ষ নাও থাকতে পারে: A{NULL, valueA} B{NULL, valueB} C{NULL, valueC}এবং [&A, &B, &C], বা সমস্ত সংঘর্ষ A{&B, valueA} B{&C, valueB}, C{NULL, valueC}এবং [NULL, &A, NULL]: NUL বালতিগুলি "নষ্ট"? কিন্ডা, কিন্ডা না। একই মোট স্মৃতি ব্যবহৃত।
টনি দেলরোয়

104

ব্যবহার এবং লিঙ্গো:

  1. হ্যাশ টেবিলগুলি দ্রুত ডেটা (বা রেকর্ড) সংরক্ষণ এবং পুনরুদ্ধার করতে ব্যবহৃত হয়।
  2. রেকর্ডগুলি হ্যাশ কী ব্যবহার করে বালতিতে সংরক্ষণ করা হয়
  3. হ্যাশ কীগুলি রেকর্ডের মধ্যে থাকা একটি বেছে নেওয়া মান ( কী মান) -এ একটি হ্যাশিং অ্যালগরিদম প্রয়োগ করে গণনা করা হয় । এই নির্বাচিত মানটি অবশ্যই সমস্ত রেকর্ডের একটি সাধারণ মান হতে হবে।
  4. প্রতিটি বালতিতে একাধিক রেকর্ড থাকতে পারে যা একটি নির্দিষ্ট ক্রমে সংগঠিত হয়।

বাস্তব বিশ্বের উদাহরণ:

1803 সালে প্রতিষ্ঠিত এবং কোনও কম্পিউটার প্রযুক্তির অভাবে হ্যাশ অ্যান্ড কোং তাদের প্রায় 30,000 ক্লায়েন্টের বিশদ তথ্য (রেকর্ড) রাখার জন্য মোট 300 ফাইলিং ক্যাবিনেট ছিল। প্রতিটি ফাইল ফোল্ডার স্পষ্টভাবে তার ক্লায়েন্ট নম্বর, 0 থেকে 29,999 এর একটি অনন্য নম্বর দিয়ে চিহ্নিত করা হয়েছিল।

সেই সময়ের ফাইলিং কেরানিদের কর্মরত কর্মীদের জন্য ক্লায়েন্টের রেকর্ডগুলি দ্রুত সংগ্রহ এবং সংরক্ষণ করতে হয়েছিল। কর্মীরা সিদ্ধান্ত নিয়েছিল যে তাদের রেকর্ডগুলি সংরক্ষণ এবং পুনরুদ্ধারে হ্যাশিং পদ্ধতি ব্যবহার করা আরও দক্ষ হবে।

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

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

আমাদের বাস্তব জগতের উদাহরণে, আমাদের বাকেট হয় ফাইলিং ক্যাবিনেটের এবং আমাদের রেকর্ড হয় ফাইল ফোল্ডার


একটি গুরুত্বপূর্ণ বিষয় মনে রাখতে হবে যে কম্পিউটারগুলি (এবং তাদের অ্যালগোরিদম) স্ট্রিংয়ের চেয়ে সংখ্যাগুলির সাথে আরও ভাল আচরণ করে। সুতরাং একটি সূচক ব্যবহার করে একটি বড় অ্যারে অ্যাক্সেস ক্রমানুসারে অ্যাক্সেস চেয়ে উল্লেখযোগ্যভাবে দ্রুত।

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

সুতরাং উপরের উদাহরণে, 30,000 সম্ভাব্য ক্লায়েন্ট বা তার চেয়ে কম জায়গায় ম্যাপ করা হয়েছে।


এর মূল ধারণাটি হ'ল আপনার সম্পূর্ণ ডেটাটিকে বিভাগগুলিতে বিভক্ত করা যা প্রকৃত অনুসন্ধানকে সাধারণত সময় ব্যয় করে তত দ্রুত করে তোলে। উপরের আমাদের উদাহরণে, 300 ফাইলিং মন্ত্রিসভার প্রত্যেকটিতে (পরিসংখ্যানগতভাবে) প্রায় 100 টি রেকর্ড থাকবে। 100 টি রেকর্ডের মাধ্যমে অনুসন্ধান (অর্ডার নির্বিশেষে) 30,000 ডিল করার চেয়ে অনেক দ্রুত is

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

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

Jeach!


2
আপনি একটি নির্দিষ্ট ধরণের হ্যাশ টেবিলের সংঘর্ষ এড়ানোর কৌশল বর্ণনা করেন, যাকে বলা হয় ভেরিয়েবল "ওপেন অ্যাড্রেসিং" বা "ক্লোজ অ্যাড্রেসিং" (হ্যাঁ, দু: খিত তবে সত্য) বা "চেইনিং"। আরও একটি ধরণের রয়েছে যা তালিকার বালতি ব্যবহার করে না বরং পরিবর্তে আইটেমগুলিকে "ইনলাইন" সঞ্চয় করে।
কনরাড রুডল্ফ

2
দুর্দান্ত বর্ণনা। প্রতিটি ফাইলিং মন্ত্রিসভা বাদে গড়ে প্রায় 100রেকর্ড (30 কে রেকর্ড / 300 ক্যাবিনেট = 100) থাকে। একটি সম্পাদনা মূল্যবান হতে পারে।
রায়ান টাক

@ টনিডি, অনলাইনে এই সাইটে শ -1 এ যান এবং TonyDআপনি পাঠ্য ক্ষেত্রে টাইপ করেন তার জন্য একটি SHA-1 হ্যাশ তৈরি করুন । আপনি দেখতে এমন কিছু তৈরির মান দিয়ে শেষ করবেন e5dc41578f88877b333c8b31634cf77e4911ed8c। এটি 160-বিট (20-বাইট) এর একটি বৃহত হেক্সাডেসিমাল সংখ্যার চেয়ে বেশি কিছু নয়। তারপরে আপনার রেকর্ডটি সঞ্চয় করতে কোন বালতি (একটি সীমিত পরিমাণ) ব্যবহৃত হবে তা নির্ধারণ করতে আপনি এটি ব্যবহার করতে পারেন।
পৌঁছা

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

2
@ টনিডি, আমি পাঠ্যটি " 300 এর মাধ্যমে হ্যাশ কীটি মডিউল করব" তে পরিবর্তন করেছি , আশা করি এটি সবার জন্য আরও পরিষ্কার এবং পরিষ্কার হবে। ধন্যবাদ!
জেচ

64

এটি তত্ত্বের একটি গভীর গভীর অঞ্চল হিসাবে প্রমাণিত হয়েছে, তবে মূল রূপরেখাটি সহজ।

মূলত, একটি হ্যাশ ফাংশনটি কেবল এমন একটি ফাংশন যা একটি স্থান থেকে জিনিস নিয়ে যায় (নির্বিচারে দৈর্ঘ্যের স্ট্রিংগুলি বলুন) এবং সূচীকরণের জন্য দরকারী স্থানে ম্যাপ করে (স্বাক্ষরযুক্ত স্বাক্ষরগুলি বলুন)।

আপনার যদি হ্যাশ করার মতো জিনিসগুলির একটি ছোট জায়গা থাকে তবে আপনি কেবল সেই জিনিসগুলিকে পূর্ণসংখ্যা হিসাবে ব্যাখ্যা করে পালিয়ে যেতে পারেন এবং আপনার কাজ শেষ হয়েছে (যেমন 4 বাইট স্ট্রিং)

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

এটি সূচিত করে আপনি এটির একই ফলাফলের সম্ভাবনা নাও চান এবং সম্ভবত আপনি সম্ভবত হ্যাশ ফাংশনটি দ্রুত হতে চান।

এই দুটি বৈশিষ্ট্যের ভারসাম্য (এবং আরও কয়েকটি) অনেক লোককে ব্যস্ত রেখে দিয়েছে!

অনুশীলনে আপনি সাধারণত এমন একটি ফাংশন সন্ধান করতে সক্ষম হন যা আপনার অ্যাপ্লিকেশনটির জন্য ভাল কাজ করে এবং এটি ব্যবহার করতে পারে।

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

আপনি যখন দীর্ঘ যান, আপনার হ্যাশটেবলে (অ্যারে) প্রতিটি প্রবেশই ফাঁকা হয় বা এতে একটি প্রবেশিকা, বা প্রবেশের তালিকা থাকে। পুনরুদ্ধার করা অ্যারেতে সূচিকাগুলির মতো সহজ, এবং হয় মানটি ফেরত দেওয়া, অথবা মানগুলির তালিকায় হাঁটা এবং সঠিকটি ফিরে আসা।

অবশ্যই অনুশীলনে আপনি সাধারণত এটি করতে পারবেন না, এটি অত্যধিক মেমরির অপচয় করে। সুতরাং আপনি একটি বিচ্ছিন্ন অ্যারের উপর ভিত্তি করে সবকিছু করেন (যেখানে কেবলমাত্র প্রবেশকারীরা আপনি প্রকৃতপক্ষে ব্যবহার করেন, বাকি সমস্ত কিছুই স্পষ্টভাবে নাল হয়)।

এই কাজটি আরও ভাল করার জন্য প্রচুর পরিকল্পনা এবং কৌশল রয়েছে তবে এটি মূল বিষয়।


1
দুঃখিত, আমি জানি এটি একটি পুরানো প্রশ্ন / উত্তর, তবে আমি আপনার এই শেষ পয়েন্টটি বোঝার চেষ্টা করছি। একটি হ্যাশ টেবিলের ও (1) সময়ের জটিলতা রয়েছে। যাইহোক, একবার আপনি একটি স্পার্স অ্যারে ব্যবহার করার পরে, আপনার মানটি খুঁজে বের করার জন্য বাইনারি অনুসন্ধান করার দরকার পড়ে না? সেই সময়ে কি জটিলতা ও (লগ এন) হয়ে যায় না?
হারব্র্যান্ডসন

@ হ্যারব্র্যান্ডসন: না ... একটি বিচ্ছিন্ন অ্যারে এর অর্থ হ'ল তুলনামূলকভাবে কয়েকটি সূচক মান সহ জনপ্রিয় হয়েছে - আপনি এখনও নিজের কী থেকে গণনা করেছেন হ্যাশ মানটির জন্য নির্দিষ্ট অ্যারে উপাদানটিতে সরাসরি সূচক করতে পারেন; তবুও, স্পার্স অ্যারে বাস্তবায়ন সাইমন বর্ণনা করে খুব সীমাবদ্ধ পরিস্থিতিতে কেবল বুদ্ধিমান : যখন বালতি মাপের মেমরি পৃষ্ঠার মাপের ক্রম হয় (বনাম int। 1-ইন -1000 স্পারনেস এবং 4 কে পৃষ্ঠাগুলিতে = কী পৃষ্ঠাগুলি স্পর্শ করে) এবং কখন ওএস সমস্ত -0 পৃষ্ঠাগুলি দক্ষতার সাথে আচরণ করে (যাতে অল-অব্যবহৃত-বালতি পৃষ্ঠাগুলি ব্যাকিং মেমোরির প্রয়োজন হয় না), যখন ঠিকানার জায়গাটি প্রচুর পরিমাণে হয় ....
টনি ডেলরয়

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

48

প্রচুর উত্তর, কিন্তু এগুলির কোনওটি খুব ভিজ্যুয়াল নয় এবং হ্যাশ টেবিলগুলি ভিজ্যুয়ালাইজ করার সময় সহজেই "ক্লিক" করতে পারে।

হ্যাশ টেবিলগুলি প্রায়শই লিঙ্কযুক্ত তালিকার অ্যারে হিসাবে প্রয়োগ করা হয়। যদি আমরা কোনও টেবিলটি মানুষের নাম সংরক্ষণের জন্য কল্পনা করি, কয়েকটি সন্নিবেশের পরে এটি নীচের মতো মেমরিতে রাখা যেতে পারে, যেখানে- ()অনুমোদিত নম্বরগুলি পাঠ / নামটির হ্যাশ মান।

bucket#  bucket content / linked list

[0]      --> "sue"(780) --> null
[1]      null
[2]      --> "fred"(42) --> "bill"(9282) --> "jane"(42) --> null
[3]      --> "mary"(73) --> null
[4]      null
[5]      --> "masayuki"(75) --> "sarwar"(105) --> null
[6]      --> "margaret"(2626) --> null
[7]      null
[8]      --> "bob"(308) --> null
[9]      null

কয়েকটি বিষয়:

  • অ্যারের প্রতিটি এন্ট্রি (সূচক [0], [1]...) বালতি হিসাবে পরিচিত , এবং একটি - সম্ভবত শূন্য - সংযুক্ত মানের তালিকা (ওরফে উপাদানসমূহ , এই উদাহরণে - লোকের নাম ) শুরু করে
  • প্রতিটি মান (যেমন "fred"হ্যাশ সহ 42) বালতি থেকে লিঙ্কযুক্ত [hash % number_of_buckets]যেমন 42 % 10 == [2]; %হয় ফরম অপারেটরের বাকি যখন buckets সংখ্যা দ্বারা বিভক্ত -
  • একাধিক ডাটা মানগুলি একই বালতি থেকে সংঘর্ষে লিঙ্ক হতে পারে, প্রায়শই কারণ হ্যাশ মানগুলি মডুলো অপারেশন (যেমন 42 % 10 == [2], এবং 9282 % 10 == [2]) পরে সংঘর্ষিত হয় তবে মাঝে মাঝে হ্যাশ মান একই হয় (যেমন "fred"এবং "jane"উভয় 42উপরে হ্যাশ দিয়ে দেখানো হয়েছে )
    • বেশিরভাগ হ্যাশ টেবিল সংঘর্ষগুলি হ্যান্ডেল করে - সামান্য হ্রাস কার্যকারিতা সহ তবে কোনও কার্যকরী বিভ্রান্তির সাথে - হ্যাশ-টু বালতিতে লিঙ্কযুক্ত তালিকায় ইতিমধ্যে সংযুক্ত তালিকায় থাকা প্রতিটি মানটির সম্পূর্ণ মান (এখানে পাঠ্য) তুলনা করে

লিঙ্কযুক্ত তালিকার দৈর্ঘ্য লোড ফ্যাক্টরের সাথে সম্পর্কিত, মানগুলির সংখ্যার সাথে নয়

যদি টেবিলের আকারটি বৃদ্ধি পায়, উপরের মতো প্রয়োগ করা হ্যাশ টেবিলগুলি বালতিতে মানগুলির অনুপাত রাখতে (উরফ লোড ) সেখানে নতুন / আপডেট লিংক তালিকা তৈরি করে, নতুন / আপডেট লিঙ্কযুক্ত তালিকা তৈরি করবে, পুরানো অ্যারে মুছবে) ফ্যাক্টর ) কোথাও 0.5 থেকে 1.0 রেঞ্জের মধ্যে।

হান্স নীচে একটি মন্তব্যে অন্যান্য বোঝার কারণগুলির জন্য আসল সূত্রটি দেয় তবে সূচক মানগুলির জন্য: লোড ফ্যাক্টর 1 এবং একটি ক্রিপ্টোগ্রাফিক শক্তি হ্যাশ ফাংশন সহ, 1 / ই (~ 36.8%) বালতি খালি থাকে, অন্য 1 / e (~ 36.8%) এর একটি উপাদান রয়েছে, 1 / (2e) বা .4 18.4% দুটি উপাদান, 1 / (3! ই) প্রায় 6.1% তিনটি উপাদান, 1 / (4! ই) বা ~ 1.5% চারটি উপাদান, 1 / (৫! ই) 3 .৩% এর পাঁচটি ইত্যাদি রয়েছে .. খালি নন বালতি থেকে চেইনের গড় দৈর্ঘ্য 1.58 ডলার হয় সারণীতে কতগুলি উপাদান থাকে (যেমন 100 টি উপাদান এবং 100 বালতি, বা 100 মিলিয়ন) উপাদান এবং 100 মিলিয়ন বালতি), তাই আমরা বলি / সন্নিবেশ / মুছুন (1) ধ্রুবক সময় ক্রিয়াকলাপ।

কীভাবে একটি হ্যাশ টেবিল মানগুলির সাথে কীগুলি সংযুক্ত করতে পারে

উপরে বর্ণিত হিসাবে একটি হ্যাশ টেবিল বাস্তবায়ন দেওয়া, আমরা কল্পনা করতে পারি যেমন একটি মান ধরণের তৈরি করা struct Value { string name; int age; };এবং সমতা তুলনা এবং হ্যাশ ফাংশনগুলি যা কেবলমাত্র nameক্ষেত্রটি দেখায় (বয়স উপেক্ষা করে) এবং তারপরে দুর্দান্ত কিছু ঘটে: আমরা টেবিলে Valueরেকর্ড সংরক্ষণ করতে পারি {"sue", 63}, তার পরে তার বয়স না জেনে "মামলা" অনুসন্ধান করুন, সঞ্চিত মানটি সন্ধান করুন এবং তার বয়স পুনরুদ্ধার করুন বা এমনকি আপডেট করুন
- জন্মদিনের শুভ শুভ - যা আকর্ষণীয়ভাবে হ্যাশটির মান পরিবর্তন করে না তাই প্রয়োজন হয় না যে আমরা মামলাটির রেকর্ডকে অন্যটিতে স্থানান্তরিত করি বালতি।

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

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

হ্যাশ টেবিল প্রয়োগের অন্যান্য উপায় রয়েছে

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


হ্যাশ ফাংশনগুলিতে কয়েকটি শব্দ

শক্তিশালী হ্যাশিং ...

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

এটি সাধারণত অঙ্ক করা আমার পক্ষে জটিল নয় এমন গণিতের দ্বারা অর্কেস্ট্রেটেড। আমি একটি সহজ-সরল বোঝার উপায় উল্লেখ করব - সর্বাধিক স্কেলযোগ্য বা ক্যাশে বান্ধব নয় বরং অন্তর্নিহিত মার্জিত (যেমন এককালীন প্যাড সহ এনক্রিপশন!) - যেহেতু আমি মনে করি এটি উপরে উল্লিখিত পছন্দসই গুণাবলী চালনা করতে সহায়তা করে। বলুন যে আপনি 64৪-বিট doubleগুলি করছেন - আপনি ২৫6 টি এলোমেলো সংখ্যার (নীচের কোড) প্রতিটি 8 টি টেবিল তৈরি করতে পারেন, তারপরে doubleস্মৃতি উপস্থাপনার প্রতিটি 8-বিট / 1-বাইট স্লাইসকে আলাদা টেবিলের সূচিতে ব্যবহার করতে পারেন, আপনি এলোমেলো নম্বর। এই পদ্ধতির সাথে, এটি দেখতে সহজ যে কিছুটা (বাইনারি ডিজিটিক অর্থে) doubleফলাফলের যে কোনও জায়গায় পরিবর্তিত হওয়া এলোমেলো সংখ্যার ফলাফলের একটি সারণীতে সন্ধান করা হবে এবং একটি সম্পূর্ণ অসামঞ্জস্যিত চূড়ান্ত মান।

// note caveats above: cache unfriendly (SLOW) but strong hashing...
size_t random[8][256] = { ...random data... };
const char* p = (const char*)&my_double;
size_t hash = random[0][p[0]] ^ random[1][p[1]] ^ ... ^ random[7][p[7]];

দুর্বল তবে দ্রুত হ্যাশিং ...

অনেক লাইব্রেরির হ্যাশিং ফাংশনগুলি অপরিবর্তিত ( তুচ্ছ বা পরিচয় হ্যাশ ফাংশন হিসাবে পরিচিত) এর মাধ্যমে পূর্ণসংখ্যার পাস করে ; এটি উপরে বর্ণিত শক্তিশালী হ্যাশিং থেকে অন্য চরম। একটি পরিচয় হ্যাশ অত্যন্তসংঘর্ষ সবচেয়ে খারাপ ক্ষেত্রে প্রবণতা রয়েছে, তবে আশাবাদটি হল যে পূর্ণসংখ্যার কীগুলির মোটামুটি সাধারণ ক্ষেত্রে যেগুলি বর্ধনশীল হয়ে থাকে (সম্ভবত কিছু ফাঁক দিয়ে) তারা এলোমেলো বালতিগুলিতে মানচিত্রটি এলোমেলো হ্যাশিং পাতার চেয়ে কিছুটা খালি রেখে দেবে (আমাদের ~ 36.8 লোড ফ্যাক্টর 1 এর পূর্বে উল্লিখিত%), যার ফলে সংঘর্ষের সংখ্যা কম এবং সংঘর্ষের উপাদানগুলির সাথে দীর্ঘতর লিঙ্কযুক্ত তালিকাগুলি এলোমেলো ম্যাপিংয়ের চেয়ে বেশি পাওয়া যায়। একটি শক্তিশালী হ্যাশ তৈরি করতে সময় লাগে তা সংরক্ষণ করাও দুর্দান্ত এবং কীগুলি ক্রমগুলি সন্ধান করা হয় তবে মেমরির নিকটবর্তী বালতিগুলিতে পাওয়া যাবে, ক্যাশে হিটগুলি উন্নত করবে। কীগুলি যখন ভালভাবে বৃদ্ধি পায় না , আশা করি তারা এলোমেলোভাবে পর্যাপ্ত হবে তাদের বালিশে স্থান নির্ধারণের জন্য এলোমেলোভাবে শক্তিশালী হ্যাশ ফাংশনের প্রয়োজন হবে না।


6
আমাকে কেবল বলার অনুমতি দিন: দুর্দান্ত উত্তর।
সিআরটিজেজে

@ টনি ডেলরয় বিস্ময়কর উত্তরের জন্য ধন্যবাদ। যদিও আমার মনে এখনও একটি ওপেন পয়েন্ট আছে। আপনি বলছেন যে 100 মিলিয়ন বালতি থাকলেও, দেখার সময় ও (1) লোড ফ্যাক্টর 1 এবং একটি ক্রিপ্টোগ্রাফিক শক্তি হ্যাশ ফাংশন সহ। তবে ১০০ কোটির মধ্যে সঠিক বালতিটি সন্ধান করার কী আছে? এমনকি যদি আমাদের সমস্ত বালতি বাছাই করা হয় তবে এটি ও (লগ 100.000.000) নয়? বালতিটি কীভাবে ও (1) পাওয়া যাবে?
Selman

@ সেলম্যান: আপনার প্রশ্নটি কেন এটি ও (লগ ১০,০০,০০০) হতে পারে বলে ব্যাখ্যা করার জন্য আপনার বিস্তৃত বিবরণ সরবরাহ করে না, তবে আপনি "আমাদের কাছে সমস্ত বালতি সাজানো থাকলেও" বলছেন - মনে রাখবেন যে হ্যাশ টেবিলের বালতিতে মান রয়েছে হয় না যা মান প্রদর্শিত হয় যা বালতি চাবি হ্যাশ ফাংশন প্রয়োগের দ্বারা নির্ধারিত হয়: চলিত অর্থে "সাজানো"। জটিলতাটি ও (লগ 100,000,000) ভেবে বোঝা যাচ্ছে আপনি বাছাই করা বালতিগুলির মাধ্যমে বাইনারি অনুসন্ধান করার কল্পনা করেছেন, তবে এটি হ্যাশিং কীভাবে কাজ করে না। হতে পারে অন্যান্য কয়েকটি উত্তর পড়ুন এবং দেখুন এটি আরও অর্থবোধ করতে শুরু করে।
টনি দেলরোয়

@ টনিডেলরয়ে প্রকৃতপক্ষে, "সাজানো বালতি" হ'ল আমি কল্পনা করি এমন সেরা পরিস্থিতি। অতএব হে (লগ 100,000,000)। তবে যদি এটি না হয় তবে অ্যাপ্লিকেশনটি কীভাবে লক্ষ লক্ষ মানুষের মধ্যে সম্পর্কিত বালতিটি খুঁজে পেতে পারে? হ্যাশ ফাংশন কি কোনওভাবে মেমরির অবস্থান তৈরি করে?
Selman

1
@ সেলম্যান: কারণ কম্পিউটার মেমরি অবিচ্ছিন্ন সময়কে "এলোমেলো অ্যাক্সেস" দেয়: আপনি যদি কোনও মেমরি ঠিকানা গণনা করতে পারেন তবে অ্যারের অন্যান্য অংশগুলিতে মেমরির অ্যাক্সেস না করেই আপনি মেমরির সামগ্রীগুলি পুনরুদ্ধার করতে পারেন। সুতরাং, আপনি প্রথম বালতি, শেষ বালতি, বা যে কোনও জায়গায় যে কোনও জায়গায় অ্যাক্সেস করুন না কেন, এতে একই কর্মক্ষমতা বৈশিষ্ট্য থাকবে (আলগাভাবে, একই পরিমাণ সময় নিন, সিপিইউ এল 1 / এল 2 / এল 3 মেমরি ক্যাশে প্রভাবের অধীনে তবে তারা কেবল আপনাকে সম্প্রতি অ্যাক্সেস করা বা কাকতালীয়ভাবে কাছের বালতিগুলিতে দ্রুত পুনরায় অ্যাক্সেস করতে সহায়তা করার জন্য কাজ করে এবং বিগ-ও বিশ্লেষণের জন্য এড়ানো যায়)।
টনি ডেলরয়

24

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

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

uint slotIndex = hashValue % hashTableSize;

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

slotIndex = (remainder + 1) % hashTableSize;

আমি মনে করি স্লট ইনডেক্স নির্ধারণের জন্য আরও আরও উন্নত পদ্ধতি থাকতে পারে তবে আমি দেখতে পেলাম এটিই সাধারণ ... আরও ভালভাবে সম্পাদনকারী যে কোনও অন্যের প্রতি আগ্রহী হবে।

মডুলাস পদ্ধতির সাথে, যদি আপনার 1000 সাইজের সাইজের একটি টেবিল থাকে তবে 1 থেকে 1000 এর মধ্যে যে কোনও হ্যাশভ্যালু সংশ্লিষ্ট স্লটে যাবে। কোনও নেতিবাচক মান এবং 1000 এর চেয়ে বড় যে কোনও মান হ'ল সম্ভাব্য সংঘর্ষের স্লট মান। ঘটনার সম্ভাবনাগুলি উভয়ই আপনার হ্যাশিং পদ্ধতির উপর নির্ভর করে, পাশাপাশি আপনি হ্যাশ টেবিলটিতে মোট কতগুলি আইটেম যুক্ত করেন তা নির্ভর করে। সাধারণত, হ্যাশট্যাবলের আকারটি তৈরি করার পক্ষে এটি সর্বোত্তম অনুশীলন যা এতে যুক্ত হওয়া মোট মানের সংখ্যা কেবল তার আকারের প্রায় 70% এর সমান। যদি আপনার হ্যাশ ফাংশনটি এমনকি বিতরণে ভাল কাজ করে, আপনি সাধারণত খুব কমই কোনও বালতি / স্লটের সংঘর্ষের মুখোমুখি হবেন এবং এটি উভয়র জন্য অনুসন্ধান এবং লেখার ক্রিয়া সম্পাদন করবে। যোগ করার জন্য মোট মানগুলির সংখ্যা আগে থেকে জানা না থাকলে, যে কোনও অর্থ ব্যবহার করে একটি ভাল অনুমান তৈরি করুন,

আমি আশা করি এটি সাহায্য করেছে

পিএস - সি # তে GetHashCode()পদ্ধতিটি বেশ ধীর এবং আমি পরীক্ষিত অনেক শর্তে প্রকৃত মান সংঘর্ষের ফলাফল। কিছু বাস্তব মজাদার জন্য, আপনার নিজের হ্যাশফঙ্কশনটি তৈরি করুন এবং এটি আপনি যে নির্দিষ্ট ডেটা হ্যাশ করছেন তার সাথে কখনও সংঘর্ষের চেষ্টা করার চেষ্টা করুন, গেটহ্যাশকোডের চেয়ে দ্রুত চালান, এবং মোটামুটি এমনকি বিতরণও করুন। আমি এটি আকারের হ্যাশকোড মানগুলির পরিবর্তে দীর্ঘ ব্যবহার করে করেছি এবং এটি 0 টি সংঘর্ষের সাথে হ্যাশ টেবিলের 32 মিলিয়ন এনটিয়ের হ্যাশভ্যালুতে বেশ ভাল কাজ করেছে। দুর্ভাগ্যক্রমে আমি কোডটি আমার নিয়োগকর্তার হিসাবে ভাগ করে নিতে পারি না ... তবে আমি প্রকাশ করতে পারি যে এটি নির্দিষ্ট ডেটা ডোমেনের পক্ষে সম্ভব। আপনি যখন এটি অর্জন করতে পারবেন, হ্যাশটেবলটি খুব দ্রুত। :)


আমি জানি পোস্টটি বেশ পুরানো তবে কেউ কী ব্যাখ্যা করতে পারেন (বাকি +1) এখানে
হরি

3
@ হারি remainderমূল মডুলো গণনার ফলাফলকে বোঝায় এবং পরবর্তী উপলব্ধ স্লটটি সন্ধান করার জন্য আমরা এতে 1 যুক্ত করি।
x4nd3r

"অ্যারে নিজেই প্রতিটি স্লটে কিছু না কিছু থাকে a ন্যূনতম সময়ে আপনি হ্যাশভ্যালু বা মানটি এই স্লটে সংরক্ষণ করবেন will" - "স্লট" (বালতি) এর জন্য কোনও মূল্য সঞ্চয় করা সাধারণ নয়; ওপেন অ্যাড্রেসিং বাস্তবায়নগুলি প্রায়শই হয় NULL বা কোনও সংযুক্ত তালিকার প্রথম নোডের পয়েন্টার - যা কোনও স্লট / বালতিতে কোনও মূল্য ছাড়াই সঞ্চয় করে। "অন্য যে কোনও ব্যক্তির সাথে আগ্রহী হবে" - আপনি যে "+1" চিত্রিত করেছেন তাকে লিনিয়ার প্রোবিং , অফ-বেটার-পারফর্মিং: চতুর্ভুজীয় প্রোব বলা হয়"সাধারণত খুব কমই কোনও বালতি / স্লটের সংঘর্ষের মুখোমুখি হয় না" - @ 70% ক্ষমতা, ~ 12% স্লট ডাব্লু / 2 মান,% 3% 3 ....
টনি ডেলরয়

"আমি ইন্ট সাইজের হ্যাশকোড মানগুলির পরিবর্তে দীর্ঘ ব্যবহার করে এটি করেছি এবং এটি 0 টি সংঘর্ষের সাথে হ্যাশ টেবিলের 32 মিলিয়ন এনটিয়ের হ্যাশভ্যালুতে বেশ ভাল কাজ করেছে।" - সাধারণ ক্ষেত্রে যেখানে বালির সংখ্যার চেয়ে অনেক বড় পরিসরে কীগুলির মান কার্যকরভাবে এলোমেলোভাবে সম্ভব তা সম্ভব নয় । মনে রাখবেন যে পৃথক হ্যাশ মান থাকা প্রায়শই যথেষ্ট সহজ (এবং আপনার longহ্যাশ মানগুলির আলাপটি আপনি যা অর্জন করেছেন তা বোঝায়), তবে মোড /% অপারেশন না হওয়ার পরে তারা হ্যাশ টেবিলের সাথে সংঘর্ষ না হওয়ার বিষয়টি নিশ্চিত করে (সাধারণ ক্ষেত্রে )।
টনি ডেলরয়

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

17

এটি আমার বোঝার ক্ষেত্রে এইভাবে কাজ করে:

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

ধরা যাক আপনার কাছে 200 টি অবজেক্ট রয়েছে তবে তাদের মধ্যে কেবল 15 টিতে হ্যাশ কোড রয়েছে যা 'বি' অক্ষর দিয়ে শুরু হয় begin হ্যাশ টেবিলের জন্য সমস্ত 200 টি অবজেক্টের চেয়ে কেবল 'বি' বালতির 15 টি বস্তুর সন্ধান এবং অনুসন্ধান করা দরকার।

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


13

স্বল্প ও মধুর:

একটি হ্যাশ টেবিল একটি অ্যারে জড়িয়ে দেয়, এটি কল করতে দেয় internalArray। আইটেমগুলি অ্যারেতে এইভাবে প্রবেশ করানো হয়:

let insert key value =
    internalArray[hash(key) % internalArray.Length] <- (key, value)
    //oversimplified for educational purposes

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

let insert key value =
    internalArray[hash(key) % internalArray.Length].AddLast(key, value)

সুতরাং, আমি যদি আমার হ্যাশ টেবিলের বাইরে কোনও আইটেম পুনরুদ্ধার করতে চাইতাম তবে আমি লিখতে পারি:

let get key =
    let linkedList = internalArray[hash(key) % internalArray.Length]
    for (testKey, value) in linkedList
        if (testKey = key) then return value
    return null

মুছে ফেলা অপারেশন লিখতে যেমন সহজ। যেমন আপনি বলতে পারেন, সংযুক্ত তালিকার আমাদের অ্যারে থেকে সন্নিবেশ, অনুসন্ধান এবং অপসারণ প্রায় O (1)।

যখন আমাদের অভ্যন্তরীণ অ্যারে খুব পূর্ণ হয়ে যায়, তখন প্রায় 85% ধারণক্ষমতায়, আমরা অভ্যন্তরীণ অ্যারের আকার পরিবর্তন করতে পারি এবং পুরানো অ্যারে থেকে সমস্ত আইটেমকে নতুন অ্যারে স্থানান্তর করতে পারি।


11

এটি তার চেয়েও সহজ।

একজন hashtable একটি অ্যারের (সাধারণত ছাড়া আর কিছুই নয় বিক্ষিপ্ত ভেক্টর কোন কী / মান জোড়া ধারণ এক)। এই অ্যারের সর্বাধিক আকার হ্যাশটেবলে ডেটা সংরক্ষণের ধরণের জন্য সম্ভাব্য মানগুলির সেটে আইটেমের সংখ্যার চেয়ে সাধারণত ছোট।

অ্যারেতে সংরক্ষণ করা হবে এমন আইটেমের মানগুলির ভিত্তিতে সেই অ্যারেতে একটি সূচক তৈরি করতে হ্যাশ অ্যালগরিদম ব্যবহার করা হয়।

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

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


10

আপনি একগুচ্ছ জিনিস এবং একটি অ্যারে নেন।

প্রতিটি জিনিসের জন্য, আপনি এটির জন্য একটি সূচক তৈরি করেন, তাকে হ্যাশ বলা হয়। হ্যাশ সম্পর্কিত গুরুত্বপূর্ণ বিষয়টি এটি অনেকটা 'ছড়িয়ে ছিটিয়ে'; আপনি দুটি অনুরূপ জিনিস অনুরূপ হ্যাশ করতে চান না।

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

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

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

বোনাস পয়েন্টগুলির জন্য, এটি তৈরি করুন যাতে আপনার হ্যাশ টেবিলটি অ্যাক্সেস হয়ে গেলে এটি পাওয়া জিনিসটিকে বালতিটির শুরুতে (যদি থাকে) সরিয়ে দেয়, তাই পরের বার এটি প্রথমবার যাচাই করা আছে।


1
শেষ পয়েন্টটির জন্য ধন্যবাদ যা প্রত্যেকে
সন্দীপ রাজু প্রভাকর

4

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

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

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

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


3

এটি দেখার আরও একটি উপায় এখানে।

আমি ধরে নিয়েছি যে আপনি অ্যারে এ এর ​​ধারণাটি বুঝতে পেরেছেন That's এটি এমন কিছু যা সূচীকরণের ক্রিয়াকলাপকে সমর্থন করে, যেখানে আপনি ইথ এলিমেন্ট, এ [আই] পেতে পারেন, এক ধাপে, যতই বড় 'এ' নয়।

সুতরাং, উদাহরণস্বরূপ, আপনি যদি এমন একদল লোকের সম্পর্কে তথ্য সঞ্চয় করতে চান যাঁর সকলেরই বিভিন্ন বয়স হয়, তবে একটি সহজ উপায় হ'ল একটি অ্যারে যথেষ্ট পরিমাণে থাকে এবং প্রতিটি ব্যক্তির বয়সকে অ্যারেতে সূচক হিসাবে ব্যবহার করেন। উপায়, আপনার যে কোনও ব্যক্তির তথ্যে এক-পদক্ষেপ অ্যাক্সেস থাকতে পারে।

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

এটিই মূল ধারণা। বয়স ব্যবহারের পরিবর্তে, ব্যক্তির যে কোনও ফাংশন যা মানগুলির ভাল প্রসার ঘটায় তা ব্যবহার করা যেতে পারে। এটি হ্যাশ ফাংশন। যেমন আপনি ASCII এর প্রতি তৃতীয় বিট ব্যক্তির নাম উপস্থাপন করতে পারেন, কিছু ক্রমে স্ক্র্যাম্বলড। সমস্ত বিষয় হ'ল আপনি একই বালতিতে খুব বেশি লোককে হ্যাশ করতে চান না, কারণ গতিটি ছোট ছোট বালতিগুলির উপর নির্ভর করে।


2

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


2

একটি হ্যাশ টেবিলটি পুরোপুরি এই বিষয়টি নিয়ে কাজ করে যে ব্যবহারিক গণনাটি এলোমেলো অ্যাক্সেস মেশিনের মডেল অনুসরণ করে অর্থাত মেমরির যে কোনও ঠিকানার মান ও (1) সময় বা ধ্রুবক সময়ে অ্যাক্সেস করা যায়।

সুতরাং, যদি আমার কাছে কীগুলির একটি মহাবিশ্ব থাকে (কোনও অ্যাপ্লিকেশনটিতে আমি ব্যবহার করতে পারি এমন সমস্ত সম্ভাব্য কীগুলির সেট, যেমন শিক্ষার্থীর জন্য রোল নম্বর, যদি এটি 4 ডিজিট হয় তবে এই মহাবিশ্বটি 1 থেকে 9999 পর্যন্ত সংখ্যার সেট) এবং একটি আমি আমার সিস্টেমে মেমরি বরাদ্দ করতে পারি এমন আকারের একটি সীমিত সংখ্যায় তাদের ম্যাপ করার উপায়, তাত্ত্বিকভাবে আমার হ্যাশ টেবিল প্রস্তুত।

সাধারণত, অ্যাপ্লিকেশনগুলিতে আমি কীভাবে হ্যাশ টেবিলটিতে যোগ করতে চাই তার সংখ্যার তুলনায় কীগুলির মহাবিশ্বের আকার অনেক বড় (আমি 1 জিবি মেমরি হ্যাশ করতে চাই না, বলুন, 10000 বা 100000 পূর্ণসংখ্যার মান কারণ তারা 32 বাইনারি পুনঃস্থাপনে কিছুটা দীর্ঘ)। সুতরাং, আমরা এই হ্যাশিং ব্যবহার করি। এটি একরকম মিশ্রিত ধরণের "গাণিতিক" অপারেশন, যা আমার বিশাল মহাবিশ্বকে মানচিত্রের একটি ছোট সেটকে মানচিত্র করে যা আমি স্মৃতিতে সামঞ্জস্য করতে পারি। ব্যবহারিক ক্ষেত্রে, প্রায়শই একটি হ্যাশ টেবিলের স্থান একই "ক্রম" (বিগ-ও) এর (প্রতিটি উপাদানের * সংখ্যাগুলির আকারের) হিসাবে থাকে, সুতরাং, আমরা খুব বেশি স্মৃতি নষ্ট করি না।

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

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

সিএলআরএস দ্বারা অ্যালগরিদমগুলির ভূমিকা বিষয়টি সম্পর্কে খুব ভাল অন্তর্দৃষ্টি সরবরাহ করে।


0

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

(void) addValue : (object) value
{
   int bucket = calculate_bucket_from_val(value);
   if (bucket) 
   {
       //do nothing, just overwrite
   }
   else   //create bucket
   {
      create_extra_space_for_bucket();
   }
   put_value_into_bucket(bucket,value);
}

(bool) exists : (object) value
{
   int bucket = calculate_bucket_from_val(value);
   return bucket;
}

যেখানে calculate_bucket_from_val()হ্যাশ ফাংশন যেখানে সব স্বতন্ত্রতা যাদু ঘটতে হবে।

থাম্বের নিয়মটি হল: প্রদত্ত মান beোকানোর জন্য, বালতিটি অবশ্যই ভ্যালু থেকে অনন্য এবং ডাইরাইবেল হতে হবে যা এটি সঞ্চয় করার কথা।

বালতি এমন কোনও স্থান যেখানে মানগুলি সঞ্চিত থাকে - এখানের জন্য আমি এটি অ্যারে সূচক হিসাবে রেখেছি, তবে এটি সম্ভবত একটি স্মৃতি অবস্থানও রয়েছে।


1
"থাম্বের নিয়মটি হ'ল: প্রদত্ত মান .োকানোর জন্য বালতিটি অবশ্যই ভ্যালু থেকে অনন্য এবং বিবিধ হতে হবে যা এটি সঞ্চয় করার কথা।" - এটি একটি নিখুঁত হ্যাশ ফাংশন বর্ণনা করে , যা প্রায়শই সংকলন সময়ে জানা কয়েকশ বা হাজার মানের জন্যই সম্ভব। বেশিরভাগ হ্যাশ টেবিলগুলিকে সংঘর্ষগুলি পরিচালনা করতে হয় । এছাড়াও, হ্যাশ টেবিলগুলি সমস্ত বালতিগুলি খালি থাকুক বা না থাকাকালীন জায়গাগুলি বরাদ্দ করে create_extra_space_for_bucket()। বালতি যদিও পয়েন্টার হতে পারে।
টনি ডেলরয়
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.