मैं हैश टेबल को समझने की कोशिश कर रहा हूं - क्या कोई मुझे यह समझा सकता है - स्पष्ट रूप से?


25

मैं php (क्षमा करें) में हैश टेबल के सही उपयोग और कार्यान्वयन को समझना चाहता हूं।

मैंने कहीं पढ़ा कि एक अनुभवी प्रोग्रामर ने एक हैश तालिका बनाई और फिर इसके माध्यम से पुनरावृति की। अब, मैं समझता हूँ कि यह गलत क्यों है, लेकिन मुझे यह जानने के लिए पूरी जानकारी नहीं है कि मेरी समझ सही है (यदि आप जानते हैं कि मेरा क्या मतलब है)।

तो क्या कोई मुझे समझा सकता है कि php में एक हैश टेबल कैसे लागू किया जाए (संभवत: एक साहचर्य सरणी) और शायद इससे भी महत्वपूर्ण बात यह है कि 'हैश' के साथ मूल्यों का उपयोग कैसे किया जाए और वास्तव में इसका क्या मतलब है?

जवाबों:


37

सरल हैश टेबल अवलोकन

एक रिफ्रेशर के रूप में, एक हैश तालिका एक डेटा संरचना में एक विशिष्ट कुंजी के तहत एक मूल्य को संग्रहीत करने का एक तरीका है। उदाहरण के लिए, मैं "a"कुंजी के नीचे मान को संग्रहीत कर सकता हूं 1, और बाद 1में हैश तालिका में कुंजी को देखकर इसे पुनः प्राप्त कर सकता हूं ।

हैश टेबल का सबसे सरल उदाहरण जो मैं सोच सकता हूं कि मेरे सिर के ऊपर एक हैश तालिका है जो केवल पूर्णांकों को संग्रहीत कर सकती है, जहां हैश तालिका प्रविष्टि के लिए कुंजी भी संग्रहीत किया जा रहा मूल्य है। मान लें कि आपकी तालिका आकार 8 की है, और यह मूल रूप से स्मृति में एक सरणी है:

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

हैश फंकशन

हैश फ़ंक्शंस आपको एक इंडेक्स देते हैं जहां पर अपने मूल्य को स्टोर करना है। इस तालिका के लिए एक बहुत ही सरल हैश फ़ंक्शन आपके द्वारा संग्रहित किए जाने वाले मान में 1 जोड़ना होगा, और फिर इसे 8 (तालिका तालिका) में मॉडिफाई करना होगा। दूसरे शब्दों में, आपका हैश फ़ंक्शन है (n+1)%8, जहां nपूर्णांक आप स्टोर करना चाहते हैं।

इंसर्ट

यदि आप इस हैश तालिका में एक मूल्य सम्मिलित करना चाहते हैं, तो आप अपने हैश फ़ंक्शन (इस मामले में (n+1)%8) को उस मूल्य पर कॉल करते हैं जिसे आप एक इंडेक्स देने के लिए सम्मिलित करना चाहते हैं। उदाहरण के लिए, यदि हम 14 सम्मिलित करना चाहते हैं, तो हम कॉल करेंगे (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 द्वारा लिया गया है। इस मुद्दे को हल करने के कई तरीके हैं, सबसे सरल है कि हमारे हैश फ़ंक्शन को बार-बार कॉल करें जब तक कि हम एक खाली स्थान नहीं पाते।

तो तर्क इस प्रकार है:

  1. (२ + १)% 3 =
  2. इंडेक्स 3 भरा हुआ है
  3. हमारे हैश फ़ंक्शन में 3 प्लग करें । ( + १)% 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 को सम्मिलित कर सकता हूं, और इसे केवल 2 में जोड़ा जाएगा:

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

लुकअप

आपकी हैश तालिका में लुकअप मान त्वरित है, यह देखते हुए कि आपकी हैश तालिका बहुत बड़े आकार की है। आप बस अपने हैश फ़ंक्शन को कॉल करें, और इंडेक्स प्राप्त करें। मान लीजिए कि आप देखना चाहते हैं कि 82 आपकी तालिका में है या नहीं। लुकअप फ़ंक्शन (82+1)%8= पर कॉल करेगा 3, और इंडेक्स में आइटम को देखेगा 3, और इसे आपके लिए लौटा देगा। यदि आपने 16 को देखा, तो लुकअप फ़ंक्शन इंडेक्स में दिखेगा 1, और देखें कि यह मौजूद नहीं है।

लुकअप Coll Collisions की जरूरत है, भी!

यदि आप मान 2 को देखने का प्रयास करते हैं, तो आपकी हैश तालिका में डेटा को पुनः प्राप्त करने के लिए डेटा को संग्रहीत करने के लिए उपयोग किए गए समान टकराव तर्क का उपयोग करना होगा। आपके हैश टेबल के काम करने के तरीके के आधार पर, आप या तो उस कुंजी को हैश करेंगे जब तक कि आपको वह प्रविष्टि नहीं मिल जाती जिसे आप ढूंढ रहे हैं (या रिक्त स्थान खोजें), या आप अपनी लिंक की गई सूची के माध्यम से तब तक पुनरावृत्ति करेंगे जब तक आपको आइटम नहीं मिल जाता (या सूची के अंत तक)

सारांश

तो, हैश टेबल जल्दी से कुंजी-मूल्य जोड़े को संग्रहीत और एक्सेस करने का एक अच्छा तरीका है। इस उदाहरण में हमने मान के रूप में एक ही कुंजी का उपयोग किया है, लेकिन असली दुनिया हैश तालिकाओं में चाबियाँ इतनी सीमित नहीं हैं। हैश फ़ंक्शन इंडेक्स बनाने के लिए कुंजियों पर काम करेगा, और फिर उस इंडेक्स पर कुंजी / मान संग्रहीत किया जा सकता है। हैश टेबल वास्तव में इसके माध्यम से पुनरावृत्त होना नहीं है, हालांकि ऐसा करना संभव है। जैसा कि आप देख सकते हैं, हैश टेबल में बहुत सारे रिक्त स्थान हो सकते हैं, और उनके माध्यम से चलना समय की बर्बादी होगी। भले ही हैश तालिका में इसके पुनरावृत्त में रिक्त स्थान लुकअप को लंघन करने के लिए तर्क है, आप लिंक सूचियों की तरह, पुनरावृत्तियों के लिए डिज़ाइन किए गए डेटा संरचना का उपयोग करके बेहतर अनुकूल होंगे।


2
ASCII कला FTW!
एंटो

2
बहुत बढ़िया जवाब। यह ध्यान देने योग्य हो सकता है कि विधि जहां प्रत्येक सूचकांक एक लिंक की गई सूची है, को चेनिंग कहा जाता है।
एलेक्सन

+1 उत्कृष्ट उत्तर, मेरे सिर से लगभग हर संदेह को बाहर निकाल दिया। एक और सवाल पूछने की जरूरत है। क्या प्रत्येक कार्यान्वयन उपयोग पूर्णांक को संग्रहीत करने के लिए हैशिंग का उपयोग करता है? या इसका उपयोग विशिष्ट मामलों के लिए किया जाता है? यदि हाँ, तो वे कौन से मामले हैं?
डेसीमल 0

@PHIfounder मुझे यकीन नहीं है अगर मैं आपके सवाल को पूरी तरह से समझ गया हूं, लेकिन कुंजी पर किया जाने वाला हैश फ़ंक्शन केवल विशिष्ट डेटा प्रकार जैसे कि पूर्णांक पर लागू करने के लिए, सामान्य होने के लिए डिज़ाइन किया गया है। यदि हम C कोड के बारे में बात कर रहे हैं, हैश तालिका को कुंजी और मान के लिए (शून्य *) स्वीकार करने के लिए डिज़ाइन किया जा सकता है और कुंजी के पॉइंटर मूल्य पर एक हैश गणना कर सकता है।
जेफ

@ जेफ वास्तव में मैं यह पूछने के लिए मूर्ख हो सकता हूं, लेकिन मैं एक कंप्यूटर की आंतरिक संरचना के बारे में बात कर रहा हूं; क्या प्रत्येक कंप्यूटर आंतरिक रूप से पूर्णांक को संदर्भित करने के लिए स्टोर करने के लिए हैश टेबल जैसी डेटा संरचना का उपयोग करता है या नहीं?
डेसीमल 0

7

हजारों पुस्तकों के साथ एक पुस्तकालय की कल्पना करो। आपको पुस्तकों को व्यवस्थित करने की आवश्यकता है ताकि आप प्रत्येक शीर्षक को जितनी जल्दी हो सके ढूंढ सकें।

ऐसा करने का एक (सामान्य) तरीका वर्णानुक्रम में पुस्तकों को क्रमबद्ध करना है। यदि आपका शीर्षक "जी" के साथ शुरू होता है, तो आप "जी" क्षेत्र पाते हैं, फिर दूसरे अक्षर की तलाश करें, "ओ" कहें, फिर "डी", "ई", "एल", अपनी खोज को संकुचित करें, और इसी तरह , जब तक आपको पुस्तक नहीं मिल जाती। यह, हालांकि, इसमें लंबा समय लग सकता है और इसके अलावा, जब नई किताबें आती हैं तो आपको कभी-कभी नए आगमन के लिए जगह बनाने के लिए अपने लेआउट को पुनर्गठित करने की आवश्यकता होती है।

वह बाइनरी सर्च है। यह अच्छा है।

हालाँकि, ऐसा करने का एक तेज़ तरीका है। मान लें कि आप सभी बुककेस और अलमारियों की गणना करते हैं, और फिर प्रत्येक पुस्तक के लिए आप एक विशेष, उम्मीद के साथ अनूठे नंबर की गणना करते हैं, जो नक्शे को एक किताबों की अलमारी / शेल्फ में बुक करते हैं, जहां किताब मिलनी चाहिए। जिस तरह से आप "कुंजी" की गणना करते हैं वह तब तक बहुत मायने नहीं रखता है जब तक कि यह एक यादृच्छिक-दिखने वाली संख्या नहीं देता है। उदाहरण के लिए, आप शीर्षक में सभी अक्षरों के वर्ण कोड जोड़ सकते हैं और फिर इसे कुछ अभाज्य संख्या से विभाजित कर सकते हैं (संभवतः सबसे अच्छा तरीका नहीं है, लेकिन वैसे भी काम करता है)।

वह हैशिंग। यह बहुत जल्दी है, क्योंकि आपको पूरे बुककेस और अलमारियों से गुजरने की ज़रूरत नहीं है, शीर्षक में अगले पत्र को देख रहे हैं। जब तक आप दो या दो से अधिक पुस्तकों को एक ही कुंजी के लिए हल नहीं करते, तब तक हैशिंग आमतौर पर एक-शॉट ऑपरेशन होता है। लेकिन यह ठीक है, आप जानते हैं कि वे एक-दूसरे के बगल में झूठ बोलते हैं और हैश फ़ंक्शन की गुणवत्ता के आधार पर, एक ही कुंजी के तहत बहुत अधिक नहीं होना चाहिए।

हैश टेबल की कुछ सीमाएँ और सीटीज़ (रिहैशिंग / रिसाइज़िंग) होती हैं, जो बाइनरी खोज को एक व्यवहार्य प्रतियोगी के रूप में चारों ओर रखती हैं। यह सभी काले और सफेद नहीं है कि किस विधि के संबंध में बेहतर है। लेकिन यह एक अलग कहानी है।

PS सीधे आपके प्रश्न का उत्तर न देने के लिए क्षमा करें (PHP में हैश टेबल लिखें), लेकिन यह विवरण है और इसे "प्रोग्रामिंग" कहा जाता है;)


2
मुझे कंप्यूटर से संबंधित समस्याओं के लिए गैर-कंप्यूटर से संबंधित स्पष्टीकरण पसंद हैं। +1
गाब्लिन

1

PHP में हैश टेबल, जहां तक ​​मेरा ज्ञान जाता है, बस एक के माध्यम से लागू किया जाता है:

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

आप तब कॉल के माध्यम से डेटा तक पहुँचते हैं जैसे:

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

आप सरणी की सामग्री पर पुनरावृति करने के लिए foreach () फ़ंक्शन का उपयोग करते हैं।

हैश टेबल्स को समझने का सबसे अच्छा तरीका है कि http://en.wikipedia.org/wiki/Hash_table की तरह कुछ पढ़ें , लेकिन मोटे तौर पर यह इस पर उबलता है: उस सरणी के अंदर हर पंक्ति के बाएं हाथ की तरफ () कॉल की कुंजी है । इन कुंजियों को हैश गणना के माध्यम से रखा जाएगा और परिणाम एक हैश है। आपने शायद एमडी 5 या एसएचए हैश को पहले देखा है, यह काफी समान दिखता है। इस हैश का एक विशिष्ट हिस्सा, आम तौर पर पहले एक्स अक्षर लेकिन कभी-कभी पूर्ण हैश का उपयोग तथाकथित 'बकेट्स' की पहचान करने के लिए किया जाएगा, जो मान (दाएं हाथ की ओर) के लिए भंडारण क्षेत्र हैं।

फिर जब भी आप अपने हैशटेबल का उपयोग करते हैं, तो आप मूल्य प्राप्त करने के लिए कुंजी का उपयोग करते हैं। कुंजी फिर से एक हैश की गणना हो जाती है और हैश का उपयोग संबंधित मूल्य को जल्दी से देखने के लिए किया जाता है। तो हैश टेबल सब कुछ सिर्फ संग्रहीत किया गया था, तो बस रैखिक की खोज की तुलना में तेजी से देखने के लिए अनुमति देते हैं। केवल नकारात्मक पक्ष यह है कि कुछ हैश कार्यान्वयन टकराव से ग्रस्त हैं, जो दो अलग-अलग कुंजी के लिए एक ही गणना की गई हैश है। सामान्य तौर पर, यह कुछ ऐसा नहीं है जिसके बारे में आपको बहुत चिंता है।

मुझे आशा है कि यह कुछ पृष्ठभूमि प्रदान करता है, लेकिन यदि आप इसमें रुचि रखते हैं तो कृपया इस विषय के बारे में अधिक पढ़ने की कोशिश करें। मेरी व्याख्या बहुत ही अल्पविकसित है और मुझे यकीन है कि वहाँ पर्याप्त छेद हैं, लेकिन इसे त्वरित स्पष्टीकरण के लिए पर्याप्त होना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.