আমি হ্যাশ টেবিলগুলি বোঝার চেষ্টা করছি - কেউ আমাকে এটি পরিষ্কারভাবে ব্যাখ্যা করতে পারে?


25

আমি পিএইচপি (দুঃখিত) এর হ্যাশ টেবিলগুলির সঠিক ব্যবহার এবং প্রয়োগ বুঝতে চাই।

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

সুতরাং কেউ আমাকে কীভাবে পিএইচপি (সম্ভবত একটি এসোসিয়েটিভ অ্যারে) একটি হ্যাশ টেবিল বাস্তবায়ন করতে পারে এবং সম্ভবত আরও গুরুত্বপূর্ণভাবে কীভাবে 'একটি হ্যাশ দিয়ে' মানগুলি অ্যাক্সেস করবেন এবং এর প্রকৃত অর্থ কী?

উত্তর:


37

সাধারণ হ্যাশ টেবিলের ওভারভিউ

রিফ্রেশার হিসাবে, একটি হ্যাশ টেবিল একটি ডেটা স্ট্রাকচারে একটি নির্দিষ্ট কী এর অধীনে মান সংরক্ষণ করার একটি উপায়। উদাহরণস্বরূপ, আমি "a"কীটির নীচে মান সঞ্চয় করতে পারি 1এবং তারপরে 1হ্যাশ টেবিলের কীটি অনুসন্ধান করে এটি পুনরুদ্ধার করতে পারি ।

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

---------------------------------
|   |   |   |   |   |   |   |   |
---------------------------------
  0   1   2   3   4   5   6   7  

হ্যাশ ফাংশন

হ্যাশ ফাংশন আপনাকে আপনার মানটি কোথায় সঞ্চয় করতে হবে তার একটি সূচক দেয়। এই টেবিলটির জন্য একটি দুর্দান্ত সাধারণ হ্যাশ ফাংশনটি হ'ল আপনি যে মানটি সংরক্ষণ করতে চান তাতে 1 যুক্ত করতে হবে এবং তারপরে এটি 8 (টেবিলের আকার) দ্বারা মোড করবে। অন্য কথায়, আপনার হ্যাশ ফাংশনটি হল (n+1)%8, nআপনি যে পূর্ণসংখ্যাটি সঞ্চয় করতে চান তা কোথায় ।

সন্নিবেশ

আপনি যদি এই হ্যাশ টেবিলের মধ্যে একটি মান সন্নিবেশ করতে চান, আপনি (n+1)%8আপনাকে একটি সূচক দেওয়ার জন্য যে মানটি সন্নিবেশ করতে চান তার উপর আপনার হ্যাশ ফাংশনটিকে (এই ক্ষেত্রে ) কল করুন । উদাহরণস্বরূপ, যদি আমরা ১৪ টি সন্নিবেশ করতে চান, আমরা কল করে (14 + 1) % 8সূচক 7পাই, তাই আমরা সূচীতে এটি মান সন্নিবেশ করতাম 7

---------------------------------
|   |   |   |   |   |   |   |14 |
---------------------------------
  0   1   2   3   4   5   6   7  

একইভাবে, আমরা 33, 82 এবং 191 এর মতো সন্নিবেশ করতে পারি:

---------------------------------
|191|   |33 |82 |   |   |   |14 |
---------------------------------
  0   1   2   3   4   5   6   7  

দুর্ঘটনায়

তবে যদি আমরা এমন কিছু প্রবেশের চেষ্টা করি যা এন্ট্রিটির সাথে সংঘর্ষ হয়? 2 সূচকে যেতে 3হবে, তবে এটি 82 দ্বারা নেওয়া হয়েছে this এই সমস্যাটি সমাধান করার একাধিক উপায় রয়েছে, সহজতমটি হ্যাশ ফাংশনটিকে বারবার কল করা এবং আমরা খালি জায়গা না পাওয়া পর্যন্ত বারবার বারবার কল করা।

সুতরাং যুক্তিটি নিম্নরূপ:

  1. (2 + 1)% 8 = 3
  2. সূচক 3 পূর্ণ
  3. আমাদের হ্যাশ ফাংশনটিতে 3 প্লাগ করুন । ( 3 + 1)% 8 = 4 , যা খালি।
  4. সূচক 4 এ আমাদের মান রাখুন ।

এখন হ্যাশ টেবিলটি দেখতে দেখতে সূচীতে 2 মান সঞ্চিত রয়েছে 4

---------------------------------
|191|   |33 |82 |2  |   |   |14 |
---------------------------------
  0   1   2   3   4   5   6   7  

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

---------------------------------
|191|   |33 |82 |   |   |   |14 |
---------------------------------
  0   1   2   3   4   5   6   7  

যদি আপনি স্মরণ করেন, (2+1)%8আমাদের সূচক দেয় 3, যা নেওয়া হয়। আপনি যদি নিজের হ্যাশ টেবিলটি পূরণ করতে না চান তবে আপনি প্রতিটি টেবিল সূচককে একটি লিঙ্কযুক্ত-তালিকা হিসাবে ব্যবহার করতে পারেন এবং সেই সূচীতে তালিকায় যুক্ত করতে পারেন। সুতরাং হ্যাশ ফাংশনটি আবার কল করার পরিবর্তে, আমরা কেবল সূচকগুলিতে তালিকায় যুক্ত করব 3:

            -----
            | 2 |
---------------------------------
|191|   |33 |82 |   |   |   |14 |
---------------------------------
  0   1   2   3   4   5   6   7  

এই তালিকাটি মেমরির যতটা অনুমতি দেবে তত বাড়তে পারে। আমি 18 sertোকাতে পারি এবং এটি কেবল 2 এ যুক্ত হবে:

            -----
            |18 |
            -----
            | 2 |
---------------------------------
|191|   |33 |82 |   |   |   |14 |
---------------------------------
  0   1   2   3   4   5   6   7  

খোঁজ

আপনার হ্যাশ টেবিলের মানগুলি সন্ধান করা দ্রুত, আপনার হ্যাশ টেবিলটি বেশ বড় আকারের given আপনি কেবল আপনার হ্যাশ ফাংশনটি কল করেন এবং সূচকটি পান। ধরা যাক আপনি দেখতে চান যে আপনার টেবিলে 82 আছে কিনা। সন্ধানের ফাংশনটি কল করবে (82+1)%8= 3, এবং সূচীতে থাকা আইটেমটি দেখতে এবং 3এটি আপনার জন্য ফিরিয়ে দেবে। আপনি যদি 16 টি দেখে থাকেন তবে সন্ধানের ফাংশনটি সূচীতে 1দেখা যাবে এবং দেখুন যে এটির অস্তিত্ব নেই।

সংঘর্ষগুলিও হ্যান্ডল করা দরকার লুপআপের!

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

সারাংশ

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


2
এএসসিআইআই আর্ট এফটিডব্লিউ!
Anto

2
দুর্দান্ত উত্তর। এটি উল্লেখযোগ্য হতে পারে যে যে পদ্ধতিতে প্রতিটি সূচক একটি লিঙ্কযুক্ত তালিকা হয় তাকে চেইনিং বলা হয়।
অ্যালেক্সন

+1 দুর্দান্ত উত্তর, প্রায় প্রতিটি সন্দেহ আমার মাথা থেকে বেরিয়ে যায়। আরও একটি প্রশ্ন জিজ্ঞাসা করা প্রয়োজন। প্রতিটি বাস্তবায়ন কি পূর্ণসংখ্যা সংরক্ষণের জন্য হ্যাশিং ব্যবহার করে? বা এটি নির্দিষ্ট ক্ষেত্রে ব্যবহৃত হয়? যদি হ্যাঁ, তবে সেগুলি কী কী?
0

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

@ জেফ আসলে এটি জিজ্ঞাসা করার জন্য আমি বোকা হতে পারি, তবে আমি একটি কম্পিউটারের অভ্যন্তরীণ কাঠামোর কথা বলছি; প্রতিটি কম্পিউটার স্টোর সঞ্চয় করতে হ্যাশ টেবিলের মতো কোনও ডেটা স্ট্রাকচার ব্যবহার করে কিনা অভ্যন্তরীণভাবে নয়?
0

7

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

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

এটি বাইনারি অনুসন্ধান। এটা ভালো.

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

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

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

পিএস আপনার প্রশ্নের সরাসরি উত্তর না দেওয়ার জন্য দুঃখিত (পিএইচপি-তে একটি হ্যাশ টেবিল লিখুন), তবে এটি বিশদ এবং এটি "প্রোগ্রামিং" নামে পরিচিত;)


2
আমি কম্পিউটার সম্পর্কিত সমস্যাগুলির জন্য কম্পিউটারবিহীন সম্পর্কিত ব্যাখ্যা পছন্দ করি। +1
গ্যাবলিন

1

পিএইচপি-তে হ্যাশ টেবিলটি যতটা আমার জ্ঞান হিসাবে যায়, কেবলমাত্র এর মাধ্যমে প্রয়োগ করা হয়:

$my_hash = array(
    1 => "Bob",
    2 => "Alice",
    3 => "Jack"
);

তারপরে আপনি কলগুলির মাধ্যমে ডেটা অ্যাক্সেস করতে পারেন:

echo $my_hash[2]; // Will echo "Alice"

অ্যারের সামগ্রীতে পুনরাবৃত্তি করতে আপনি foreach () ফাংশনটি ব্যবহার করেন।

হ্যাশ টেবিলগুলি বোঝার সর্বোত্তম উপায় হ'ল http://en.wikedia.org/wiki/Hash_table এর মতো কিছু পড়া , তবে মোটামুটি এটি এতে ফোটে: অ্যারে () কলের অভ্যন্তরে প্রতিটি লাইনের বাম দিকে কীগুলি হ'ল । এই কীগুলি একটি হ্যাশ গণনার মাধ্যমে দেওয়া হবে এবং ফলাফলটি একটি হ্যাশ। আপনি সম্ভবত এমডি 5 বা এসএইচএ হ্যাশগুলি আগে দেখেছেন, এটি এর সাথে বেশ মিল দেখায়। এই হ্যাশটির একটি নির্দিষ্ট অংশ, সাধারণত প্রথম এক্স অক্ষর তবে কখনও কখনও সম্পূর্ণ হ্যাশ তথাকথিত 'বালতি' সনাক্ত করতে ব্যবহৃত হবে, যা মানগুলির (ডানদিকে) স্টোরেজ অঞ্চল।

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

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

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