কেন একটি (সংঘর্ষ-কম) হ্যাশটেবল লকউইচটি সত্যই হে (1)?


10

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

আমার প্রশ্ন হচ্ছে কেন collision- হয় কম অনুসন্ধান O(1)প্রথম স্থানে?

ধরে নেওয়া যাক আমার কাছে এই হ্যাশটেবল রয়েছে:

Hash  Content
-------------
ghdjg Data1
hgdzs Data2
eruit Data3
xcnvb Data4
mkwer Data5
rtzww Data6

এখন আমি কীটির সন্ধান করছি kযেখানে হ্যাশ ফাংশন h(k)দেয় h(k) = mkwer। তবে অনুসন্ধানটি কীভাবে "জানতে পারে" যে হ্যাশটি mkwerপজিশনে রয়েছে? এটি খুঁজে পেতে কেন এটি সমস্ত কী দিয়ে স্ক্রোল O(n)করতে হবে না? হ্যাশগুলি কোনও ধরণের আসল হার্ডওয়্যার অ্যাড্রেস হতে পারে না কারণ আমি ডেটাটি সরাতে অক্ষমতা হারাব। এবং যতদূর আমি জানি, হ্যাশ টেবিলগুলি হ্যাশগুলিতে বাছাই করা হয়নি (এটি থাকলেও অনুসন্ধানও গ্রহণ করবে O(log n))?

কীভাবে একটি হ্যাশ জেনে টেবিলের সঠিক স্থান খুঁজে পেতে সহায়তা করে?

উত্তর:


24

হ্যাশ ফাংশন কিছু স্ট্রিং যেমন ফিরে নাmkwer । এটি অ্যারেতে আইটেমের অবস্থানটি সরাসরি প্রদান করে। উদাহরণস্বরূপ, যদি আপনার হ্যাশ টেবিলের দশটি প্রবেশ থাকে, হ্যাশ ফাংশনটি 0-9 সীমাতে একটি পূর্ণসংখ্যা ফেরত দেবে।


1
ধন্যবাদ। :) আমার ভুলটি MD5 বা SHA এর মতো হ্যাশটেবল হ্যাশ ফাংশনের কথা ভাবছিল। তবে একটি হ্যাশ অবশ্যই একটি পূর্ণসংখ্যার অবস্থান হতে পারে, যা আমি ভাবিনি। এখন আমি কী কী সন্ধান করতে হবে তা আমি খুব শীঘ্রই একটি ভাল উদাহরণ পেয়েছি: পিএইচপি এর হ্যাশ ফাংশন: github.com/php/php-src/blob/PHP-5.6.10/Zend/zend_hash.h#L237
ফু

13
@ ফুবার: এমডি 5 এবং এসএএচএও ইনপুট থেকে একক সংখ্যা গণনা করে, হেক্স আকারে হ্যাশগুলি নিয়ে কথা বলা ঠিক এত সাধারণ। ঠিক যেমন স্মৃতি ঠিকানা দশমিক বিবেচনা করা হয়।
nPress325681

4
প্লাস, এমডি 5 ইত্যাদি সরাসরি অ্যারে সূচক হিসাবে ব্যবহার করা খুব দীর্ঘ। নীচের এন বিটের মতো হ্যাশের কিছু অংশ ব্যবহার করা সম্ভব হবে ।
চিরলু

6

হ্যাশ ফাংশন প্রদত্ত স্ট্রিং থেকে অ্যারে অবস্থানের গণনা করে । যদি এটি নিখুঁত হ্যাশ হয় তবে এর অর্থ হ'ল নিশ্চিত যে কোনও সংঘর্ষ নেই, সম্ভবত অ্যারির সংখ্যার চেয়ে কমপক্ষে দ্বিগুণ বড় bigger

উদাহরণস্বরূপ আমি অক্ষরের জন্য খুব দুর্বল হ্যাশ দেব, কেবল ইলাস্ট্রেট মেকানিজমিকে:
0) 1) স্ট্রিংয়ের প্রতিটি চরিত্রের জন্য ascii মান গ্রহণ করুন, এটি যদি ছোট ক্ষেত্রে হয় তবে 'a' বিয়োগ করুন, উপরের ক্ষেত্রে যদি 'A' বিয়োগ করুন, মানটিতে x যোগ করুন। x = x m o d 52 2) ফলাফল সংখ্যা 15 যেমন অ্যারের সূচক। এক্স=0;
এক্স=এক্সমি52

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

এটি কারণ স্ট্রিং থেকে হ্যাশ গণনা করা কতটা পরিশীলিত ফাংশন গণনা করা যায় তার উপর নির্ভর করে তবে উপাদানগুলির সংখ্যার উপর নির্ভর করে না।হে(1)

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

এন-টিএন*(গুলিআমিz- রমিএনটি)


1
এবং অনুসন্ধান কীভাবে জানতে পারে যে টেবিলের কোথায় হ্যাশ রয়েছে? এটি অর্ডার বা হার্ডওয়্যার ঠিকানা নয়।
ফু বার

("এক্সএনবনাম")=8

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

এইচএকটিএইচএকটি(("এক্সএনবনাম"))=এইচএকটি[90]

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

3

ডেভিড রিচারির উত্তরটি প্রসারিত করতে, " হ্যাশ ফাংশন " শব্দটি কিছুটা বেশি বোঝা হয়ে গেছে। প্রায়শই, যখন আমরা একটি হ্যাশ ফাংশন সম্পর্কে কথা বলি তখন আমরা এমডি 5, এসএএএ -1, বা জাভা .hashCode()পদ্ধতির মতো এমন কিছু বিষয় চিন্তা করি যা কিছু ইনপুটকে একক সংখ্যায় রূপান্তর করে। তবে এই সংখ্যা ডোমেইন খুব অসম্ভাব্য hashtable আপনি ডেটা সংরক্ষণ করার চেষ্টা করছেন হিসাবে একই আকার হতে (অর্থাত সর্বোচ্চ মান) (MD5, 16 বাইট রয়েছে SHA-1 20 বাইট, এবং। .hashCode()একটি হল int- 4 বাইটস)।

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

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

মিমি

()=মি

...

মিমিমি=2পি()পি

Al আলগোরিদিমগুলির পরিচিতি, .311.3.1 - সিএলআরএস

মি

জাভা HashMapবিভাগ বিভাগের একটি সংশোধিত সংস্করণ ব্যবহার করে যা দুর্বল .hashCode()বাস্তবায়নের জন্য অ্যাকাউন্টে প্রাক-প্রসেসিং পদক্ষেপ করে যাতে এটি দুটি-আকারের পাওয়ারের অ্যারে ব্যবহার করতে পারে। .getEntry()পদ্ধতিতে ঠিক কী ঘটছে তা আপনি দেখতে পাবেন (মন্তব্যগুলি আমার):

 // hash() transforms key.hashCode() to protect against bad hash functions
 int hash = (key == null) ? 0 : hash(key.hashCode());
 // indexOf() converts the resulting hash to a value between 0 and table.length-1
 for (Entry<K,V> e = table[indexFor(hash, table.length)];
     ...

জাভা 8 একটি পুনর্লিখনের সাথে নিয়ে এসেছিল HashMapযার আরও দ্রুত, তবে পড়তে একটু শক্ত। এটি সূচক দেখার জন্য একই সাধারণ নীতিটি ব্যবহার করে।

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