Хеш-таблиці проти асоціативних масивів


84

Нещодавно я читав про хеш-таблиці у дуже відомій книзі " Вступ до алгоритмів ". Я ще не використовував їх у жодному реальному додатку, але хочу. Але я не знаю, як почати.
Хто-небудь може дати мені деякі зразки його використання, наприклад, як реалізувати словниковий додаток (наприклад, ABBYY Lingvo) за допомогою хеш-таблиць?
І нарешті, я хотів би знати, в чому різниця між хеш-таблицями та асоціативними масивами в PHP, я маю на увазі, яку технологію слід використовувати і в яких ситуаціях?
Якщо я помиляюся (прошу вибачення), будь ласка, виправте мене, бо насправді я починаю з хеш-таблиць і маю про них лише базові (теоретичні) знання.
Дуже дякую.


Відповіді:


123

У PHP асоціативні масиви реалізовані як хештеги з невеликою кількістю додаткової функціональності.

Однак технічно кажучи, асоціативний масив не є ідентичним хеш-таблиці - він просто реалізований частково з хеш-таблицею за лаштунками. Оскільки більша частина його реалізації є хеш-таблицею, вона може робити все, що може хеш-таблиця, але може робити і більше.

Наприклад, ви можете прокручувати асоціативний масив, використовуючи цикл for, чого не можна зробити за допомогою хеш-таблиці.

Отже, хоча вони схожі, асоціативний масив насправді може зробити надмножину того, що може зробити хеш-таблиця - отже, це не зовсім одне і те ж. Подумайте про це як про хештеги плюс додаткову функціональність.

Приклади коду:

Використання асоціативного масиву як хеш-таблиці :

$favoriteColor = array();
$favoriteColor['bob']='blue';
$favoriteColor['Peter']='red';
$favoriteColor['Sally']='pink';
echo 'bob likes: '.$favoriteColor['bob']."\n";
echo 'Sally likes: '.$favoriteColor['Sally']."\n";
//output: bob likes blue
//        Sally likes pink

Цикл через асоціативний масив :

$idTable=array();
$idTable['Tyler']=1;
$idTable['Bill']=20;
$idTable['Marc']=4;
//up until here, we're using the array as a hashtable.

//now we loop through the array - you can't do this with a hashtable:
foreach($idTable as $person=>$id)
    echo 'id: '.$id.' | person: '.$person."\n";

//output: id: 1 | person: Tyler
//        id: 20 | person: Bill
//        id: 4 | person: Marc

Особливо зверніть увагу, як у другому прикладі підтримується порядок кожного елемента (Тайлер, Білл Марк) на основі порядку, в якому вони були введені в масив. Це основна різниця між асоціативними масивами та хеш-тегами. Хеш-таблиця не підтримує зв'язку між елементами, які вона містить, тоді як асоціативний масив PHP це робить (ви навіть можете сортувати асоціативний масив PHP).


3
Мда, таке коротке пояснення. Тож вони АБСОЛЮТНО одне і те ж?
Бахтійор

2
@Bak Вони, як правило, не є, але вони працюють на PHP, який трохи швидко і вільно грає зі структурами даних, оскільки менше занепокоєння щодо продуктивності
Майкл Мрозек,

Я розумію, але в цьому випадку, чому так багато алгоритмів хеш-функцій і подібних речей, якщо хеш-функція = масиви?
Бахтійор

4
@ Michael, ти робиш це як недолік? Це робить PHP різним, але я думаю, що це хороша різниця.

1
@Bakhityor: Ваше останнє речення ідеальне. Вам не потрібно "забувати" про хештеги - насправді чудово, що ви вже розумієте хештеги, адже тепер ви можете застосувати ці знання до асоціативних масивів. Я додаю кілька прикладів до своєї відповіді, щоб ще більше пояснити для вас щось.
Cam

21

масиви php - це, в основному, хеш-таблиці


Редагувати: Ах - бийте мене :) +1.
Cam

ось що я шукав :)
Faizan

10
у жодному разі. хеш-таблиця потребує певного дозволу на зіткнення, якого в масивах php немає. Їх стратегія вирішення зіткнень просто замінює старе значення, і це не хеш-таблиця за визначенням.
Хуан

4
Наскільки я пам’ятаю, роздільна здатність зіткнень у хеш-таблицях стосується хешованого ключа, а не оригінального ключа (як це мало працювати?)
Емануель Остер,

18

Різниця між асоціативним масивом та хеш-таблицею полягає в тому, що асоціативний масив є типом даних, тоді як хеш-таблиця є реалізацією даних. Очевидно, що тип асоціативного масиву дуже важливий у багатьох сучасних мовах програмування: Perl, Python, PHP тощо. Хеш-таблиця є основним способом реалізації асоціативного масиву, але не зовсім єдиним способом. А асоціативні масиви - основне використання хеш-таблиць, але не зовсім єдине. Отже, справа не в тому, що вони однакові, але якщо у вас вже є асоціативні масиви, то зазвичай вам не слід турбуватися про різницю.

З міркувань продуктивності може бути важливо знати, що ваші асоціативні масиви улюбленою мовою реалізовані як хеші. І може бути важливо мати якесь уявлення про накладні витрати на цю реалізацію. Хеш-таблиці повільніші і використовують більше пам'яті, ніж лінійні масиви, як ви бачите їх у C.

Perl об'єднує ці два поняття, називаючи асоціативні масиви "хешами". Як і ряд особливостей Perl, це не зовсім неправильно, але це неакуратно.


7

Масив у PHP насправді є впорядкованою картою, а не хеш-таблицею. Основна відмінність між картою та хеш-таблицею полягає в неможливості запам'ятати порядок, в якому були додані елементи. З іншого боку, хештеги набагато швидші, ніж карти. Складність отримання елемента з карти - O (nlogn), а з хеш-таблиці - O (1).


4
"Складність отримання елемента з карти - O (nlogn)" - це просто неправда. Навіть для LinkedList отримання цього елемента є лише O (n). Більше того, як зазначено на en.wikipedia.org/wiki/Hash_table , хеш-таблиця, яка використовується в PHP для реалізації асоціативного масиву, має пошук O (1)
StackG

1
Як пояснено тут після перевірки вихідного коду, асоціативні масиви в PHP реалізовані як хеш-таблиці, де "кожне значення, що зберігається в хеші, пов'язане зі значенням, що зберігається до нього, і значенням, що зберігається після" як пов'язаний список. Тому він використовує для цього додаткову пам’ять, але доступ до певного елемента за допомогою ключа є настільки ж швидким, як звичайна хеш-таблиця, O (1), а не повільніше.
Леопольдо Санчик

2

Асоціативний масив - це масив, де ви отримуєте доступ до елементів не за допомогою індексу, а за допомогою ключа. Те, як це працює внутрішньо, залежить від реалізації (немає правила, як це має працювати). Асоціативний масив може бути реалізований хеш-таблицею (більшість реалізацій це зробить), але він також може бути реалізований за допомогою якоїсь деревної структури або списку пропуску, або алгоритм просто перебирає всі елементи масиву і шукає ключ що відповідає (це було б дуже повільно, але це працює).

Хеш-таблиця - це спосіб зберігання даних там, де значення пов'язані з ключами, і де ви маєте намір знайти значення для ключів протягом (зазвичай майже) постійного часу. Це звучить точно так, як ви очікуєте від асоціативного масиву, тому більшість часу хеш-таблиці використовуються для реалізації цих масивів, але це не є обов'язковим.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.