freeCodeCamp/guide/arabic/miscellaneous/hash-tables-and-hashing-fun.../index.md

166 lines
10 KiB
Markdown

---
title: Hash Tables and Hashing Functions
localeTitle: جداول تجزئة ووظائف تجزئة
---
### مقدمة عن التجزئة
تم تصميم Hashing لحل مشكلة الحاجة إلى العثور على عنصر أو تخزينه بكفاءة في مجموعة.
على سبيل المثال ، إذا كانت لدينا قائمة تضم 10000 كلمة باللغة الإنجليزية ونريد التحقق مما إذا كانت كلمة معينة موجودة في القائمة ، فسيكون من غير المقبول مقارنة الكلمة مع جميع العناصر الـ 10000 حتى نجد تطابقًا. حتى لو تم تصنيف قائمة الكلمات معجميًا ، كما هو الحال في القاموس ، ستظل بحاجة إلى بعض الوقت للعثور على الكلمة التي تبحث عنها.
تجزئة هو تقنية لجعل الأشياء أكثر كفاءة من خلال تضييق نطاق البحث في البداية.
## ما هو التجزئة؟
يعني Hashing استخدام بعض الوظائف أو الخوارزمية لتعيين بيانات الكائن إلى بعض القيم العددية التمثيلية.
يمكن استخدام رمز التجزئة هذا (أو التجزئة ببساطة) كطريقة لتضييق نطاق البحث عند البحث عن العنصر في الخريطة.
بشكل عام ، تُستخدم رموز التجزئة هذه لإنشاء فهرس ، يتم فيه تخزين القيمة.
## كيف يعمل التجزئة
في جداول التجزئة ، يمكنك تخزين البيانات في نماذج أزواج المفاتيح والقيم. يتم إعطاء المفتاح ، الذي يستخدم لتحديد البيانات ، كمدخل لوظيفة التجزئة. ثم يتم تعيين رمز التجزئة ، وهو عدد صحيح ، إلى الحجم الثابت لدينا.
يجب أن تدعم جداول التجزئة 3 وظائف.
* إدراج (مفتاح ، قيمة)
* احصل على مفتاح)
* حذف (مفتاح)
بحت كمثال لمساعدتنا على فهم المفهوم ، دعونا نفترض أننا نريد تعيين قائمة بمفاتيح السلسلة لقيم السلسلة (على سبيل المثال ، خريطة قائمة البلدان إلى مدن عاصمتهم).
لنفترض أننا نريد تخزين البيانات في الجدول في الخريطة.
مفتاح | القيمة
\---------------- | -------------
كوبا هافانا
انكلترا | لندن
فرنسا | باريس
اسبانيا | مدريد
سويسرا | برن
ودعونا نفترض أن وظيفة هاش لدينا هي ببساطة أن تأخذ طول السلسلة.
بالنسبة إلى البساطة ، سيكون لدينا صفيفان: واحد لمفاتيحنا والآخر للقيم.
لذلك ، لوضع عنصر في جدول التجزئة ، نحسب رمز التجزئة الخاص به (في هذه الحالة ، ببساطة حساب عدد الأحرف) ، ثم ضع المفتاح والقيمة في المصفوفات في الفهرس المقابل.
على سبيل المثال ، لدى كوبا رمز هاش (طول) من 4.
لذلك نقوم بتخزين كوبا في المركز الرابع في صفيف المفاتيح ، وهافانا في المؤشر الرابع لصفيف القيم وما إلى ذلك ، وننتهي بما يلي:
الموقف مجموعة مفاتيح | مجموعة القيم
\--------------------- | ------------------ | --------- ------
1 | |
2 | |
3 | |
4 | كوبا هافانا
5 | اسبانيا | مدريد
6 | فرنسا | باريس
7 | انكلترا | لندن
8 | |
9 | |
10 | |
11 | سويسرا | برن
الآن ، في هذا المثال المحدد ، تعمل الأشياء بشكل جيد.
يجب أن تكون صفيفنا كبيرًا بما يكفي لاستيعاب أطول سلسلة ، ولكن في هذه الحالة لا يوجد سوى 11 فتحة.
نحن نهدر قليلاً من المساحة لأنه ، على سبيل المثال ، لا توجد مفاتيح من حرف واحد في بياناتنا ، ولا مفاتيح بين 8 و 10 أحرف. لكن في هذه الحالة ، الفضاء المهدر ليس سيئًا أيضًا. يعتبر أخذ طول السلسلة أمرًا رائعًا وسريعًا ، وكذلك عملية العثور على القيمة المرتبطة بمفتاح معين (وبالتأكيد أسرع من إجراء خمس مقارنات للأوتار).
ولكن ، ماذا نفعل إذا كانت مجموعة البيانات تحتوي على سلسلة تحتوي على أكثر من 11 حرفًا؟
ماذا لو كان لدينا كلمة أخرى تحتوي على 5 أحرف ، "الهند" ، وحاول تعيينها إلى فهرس باستخدام الدالة hash. بما أن المؤشر 5 مشغول بالفعل ، علينا أن نتصل على ما يجب فعله به. وهذا ما يسمى الاصطدام.
إذا كانت مجموعة البيانات الخاصة بنا تحتوي على أحرف بألف حرف ، وقمت بإنشاء مجموعة من آلاف المؤشرات لتخزين البيانات ، فسوف ينتج عنها إهدار مساحة. إذا كانت مفاتيحنا عبارة عن كلمات عشوائية من الإنجليزية ، حيث توجد العديد من الكلمات بنفس الطول ، باستخدام الطول كوظيفة تجزئة ستكون عديمة الفائدة إلى حد ما.
## التعامل مع التصادم
يتم استخدام طريقتين أساسيتين للتعامل مع الاصطدامات.
1. تسلسل منفصلة
2. فتح العنونة
#### تسلسل منفصلة
يستخدم التعامل مع اصطدام التجزئة بواسطة تسلسل منفصل ، بنية بيانات إضافية ، قائمة مفضلة بشكل مفضّل للتخصيص الديناميكي ، إلى دلاء. في مثالنا ، عندما نضيف الهند إلى مجموعة البيانات ، يتم إلحاقها بالقائمة المرتبطة المخزنة في الفهرس 5 ، ثم يبدو جدولنا هكذا.
الموقف رؤساء قائمة مرتبطة |
\--------------------- | ---------------------------- -------- |
1 | |
2 | |
3 | |
4 | [كوبا-هافانا\]
5 | \[اسبانيا - مدريد\] -> \[الهند - دلهي\] |
6 | \[فرنسا باريس\] |
7 | \[إنجلترا - لندن\] |
8 | |
9 | |
10 | |
11 | \[سويسرا برن\]](https://en.wikipedia.org/wiki/Linear_probing)
للعثور على عنصر ، نذهب أولاً إلى الدلو ثم نتبادل المفاتيح. هذه طريقة شائعة ، وإذا تم استخدام قائمة الارتباطات لا يتم تعبئة التجزئة. تكلفة `get(k)` هي في المتوسط `O(n)` حيث n هي عدد المفاتيح في المجموعة ، يكون العدد الإجمالي للمفاتيح هو N.
المشكلة مع تسلسل منفصلة هو أن بنية البيانات يمكن أن تنمو خارج الحدود.
#### فتح العنونة
لا تقدم معالجة مفتوحة أي بنية بيانات جديدة. في حالة حدوث تصادم ، فإننا نبحث عن التواجد في النقطة التالية التي تم إنشاؤها بواسطة خوارزمية. يتم استخدام Open Addressing عادة عندما تكون مساحة التخزين عبارة عن معالجات مقيدة ، أي المعالجات المضمنة. فتح العنوان ليس بالضرورة أسرع ثم فصل التسلسل.
طرق لفتح العنان
* \[تحليل خطي
* [تحقيقات تربيعية](https://en.wikipedia.org/wiki/Quadratic_probing)
* [مزدوج تجزئة](https://en.wikipedia.org/wiki/Double_hashing)
## كيفية استخدام التجزئة في التعليمات البرمجية.
#### الثعبان
` # Few languages like Python, Ruby come with an in-built hashing support.
# Declaration
my_hash_table = {}
my_hash_table = dict()
# Insertion
my_hash_table[key] = value
# Look up
value = my_hash_table.get(key) # returns None if the key is not present || Deferred in python 3, available in python 2
value = my_hash_table[key] # throws a ValueError exception if the key is not present
# Deletion
del my_hash_table[key] # throws a ValueError exception if the key is not present
# Getting all keys and values stored in the dictionary
keys = my_hash_table.keys()
values = my_hash_table.values()
`
![:rocket:](//forum.freecodecamp.com/images/emoji/emoji_one/rocket.png?v=2 ":صاروخ:") [تشغيل الكود](https://repl.it/CVtK)
#### جافا
` // Java doesn't include hashing by default, you have to import it from java.util library
// Importing hashmaps
import java.util.HashMap;
// Declaration
HashMap<Integer, Integer> myHashTable = new HashMap<Integer, Integer>(); // declares an empty map.
// Insertion
myHashTable.put(key, value);
// Deletion
myHashtable.remove(key);
// Look up
myHashTable.get(key); // returns null if the key K is not present
myHashTable.containsKey(key); // returns a boolean value, indicating the presence of a key
// Number of key, value pairs in the hash table
myHashTable.size();
`
![:rocket:](//forum.freecodecamp.com/images/emoji/emoji_one/rocket.png?v=2 ":صاروخ:") [تشغيل الكود](https://repl.it/CVt1)
## مصادر
* لمزيد من القراءة ، تريد العديد من محاولة هذا [الارتباط](http://geeksquiz.com/hashing-set-1-introduction/) ، والذي يشرح التجزئة باستخدام مثال مختلف.
* [تجزئة في 60 ثانية](https://www.youtube.com/watch?v=x05KubVlh_M) .
* [تجفيف الوقواق](https://www.youtube.com/watch?v=HRzg0SzFLQQ)
* [تصانيف التجزئة](https://www.youtube.com/watch?v=jznJKL0CrxM)
* [بلوم مرشحات](https://www.youtube.com/watch?v=-SuTGoFYjZs)
* [استراتيجيات تجزئة](https://www.youtube.com/watch?v=D65JQ0qQwZk)
* [كلمة السر](https://crackstation.net/hashing-security.htm)
* [الفرق بين الفرز والتشفير](http://stackoverflow.com/questions/326699/difference-between-hashing-a-password-and-encrypting-it)