|
1 / 1 / 2
Регистрация: 25.08.2012
Сообщений: 108
|
|
Программирование без использования условных конструкций27.11.2016, 14:42. Показов 2860. Ответов 19
Метки нет (Все метки)
Ребят, задали на собеседовании такую задачку:
Есть метод с тремя параметрами - bool flag, del1 a,del1 b. Необходимо реализовать этот метод так, что бы в зависимости от флага вызывался нужный делегат. Все ничего, вот только надо сделать так, что бы в реализации не было логических операций(if,else,case...). Была подсказка использовать hash-совместимые контейнеры типа dictionary. Но я так и не придумал верного решения. Может кто знает как это должно выглядеть? Спасибо.
0
|
|
| 27.11.2016, 14:42 | |
|
Ответы с готовыми решениями:
19
Написать программу подсчета в тексте количества условных конструкций |
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
|||||||
| 27.11.2016, 14:57 | |||||||
Сообщение было отмечено Olejan_one как решение
Решение
1
|
|||||||
|
442 / 410 / 132
Регистрация: 21.01.2012
Сообщений: 976
|
||||||
| 27.11.2016, 14:57 | ||||||
Сообщение было отмечено Olejan_one как решение
Решение
1
|
||||||
|
1 / 1 / 2
Регистрация: 25.08.2012
Сообщений: 108
|
|
| 27.11.2016, 15:17 [ТС] | |
|
Ох, спасибо ребят, все оказывается намного легче чем я думал. Просто никогда с дикшенари не работал еще. Еще небольшой вопросик по поводу хештейбл и дикшенари. Где можно почитать удобную информацию о этих коллекциях? В гугле искал, но то что нашел не очень воспринимается. Может есть книги, где доступно описано хеширование и использование этих коллекций? Спасибо.
0
|
|
|
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
|
||||||
| 28.11.2016, 10:45 | ||||||
|
Olejan_one, в принципе, если без использования if`ов, то можно было и так сделать:
0
|
||||||
|
14145 / 9374 / 1350
Регистрация: 21.01.2016
Сообщений: 35,307
|
||
| 28.11.2016, 10:48 | ||
|
3
|
||
|
1 / 1 / 2
Регистрация: 25.08.2012
Сообщений: 108
|
||
| 28.11.2016, 15:17 [ТС] | ||
|
1. Собственно, насколько я понял суть хешей в контексте коллекций состоит в том, что можно быстро найти нужный элемент. Мне не очень ясен сам алгоритм поиска - Поправьте меня если не правильно описываю: а) Класс, который реализует ключи должен переопределять метод GetHashCode(). б) Соответственно получается что например при поиске ключа "Саша" словарь хеширует строку "Саша" и получает хеш, к примеру 122345. в) дальше начинается перечисление ключей и вызов метода GetHashCode() на каждом элементе для сравнения с хешем 122345? По моему результат будет долгим. Или я что то не так понял. 2. Мне не понятно что такое "емкость словаря или Capacity". Я привык к свойству Count. Соответственно сколько элементов добавилось, такая и емкость коллекции. Добавилось 5 элементов - коллекция динамически возрастает на это количество. А что такое емкость словаря не пойму, и почему она может отличаться от количества элементов, которые находятся в словаре. 3. В случае возникновения коллизии есть 2 метода реализации: а) Метод линейного поиска - объекты, ключи которых образуют одинаковый хеш преобразуются в линейный односвязный список, каждый элемент в котором содержит адрес следующего элемента в списке. У меня вопрос - у нас есть значение "Маша", образующее хеш 65478. В словаре есть еще 50 элементов, которые возвращают такой же как и у "Маши" хеш - 65478. Соответственно у нас по значению хеша 65478 - появляется линейный список из 51 элемента. Как в этом случае происходит поиск по этому линейному списку? Как нам найти значение "Маша"? На этом этапе словарь использует уже не значение хеша а сам ключ "Маша" и сравнивает его с каждым ключом списка? б) Метод открытой адресации: тут почти все понятно. Элементы с одинаковым хешем помещаются не в список, а друг за другом по словарю, в первую пустую позицию после элемента с которым совпал хеш. Вопрос: в каждой статье пишут, что в этом случае элементы должны распределяться равномерно по словарю. Это как? Допустим есть элемент "Саша" с хешем 45678 и элемент "Маша" с таким же хешем 45678. В итоге мы вставляем Сашу в ячейку под номером 45678. Далее следующая ячейка под номером 45679 уже занята другим элементом. В итоге Машу мы вставляем в следующую свободную ячейку - к примеру 45680. Что в итоге получилось: 45678 - Саша 45679 - Коля 45680 - Маша В чем заключается равномерность данного словаря? Спасибо. Буду благодарен за любой ответ.
0
|
||
|
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
|
||||
| 28.11.2016, 15:29 | ||||
|
1
|
||||
|
1 / 1 / 2
Регистрация: 25.08.2012
Сообщений: 108
|
|||
| 28.11.2016, 15:51 [ТС] | |||
|
Добавлено через 3 минуты
0
|
|||
|
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
|
|
| 28.11.2016, 15:52 | |
|
1
|
|
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||||||||||||
| 28.11.2016, 17:50 | ||||||||||||
|
Так же он должен переопределить Equals и желательно (но не обязательно) реализовать интерфейс IEquatable. Потому что если два объекта равны через метод Equals, то они должны генерировать и одинаковый хэш. Словарь группирует все добавляемые значения по их хэшу. Когда вы делаете поиск, то высчитывается хэш только того ключа, который вы передали для поиска — чтобы определить группу, в которой должно находиться искомое значение. Дальше идет линейный поиск по всем элементам в этой группе. Это будет очень накладно и медленно — попробуйте для развлечения реализовать свой динамический массив MyList<T> с предложенным вами механизмом. Чтобы не копировать весь массив при каждом добавлении, динамические коллекции, которые в качестве детали реализации используют обычный массив, выделяют память с запасом. Count показывает 5 элементов, а массив в кишках коллекции выделен на 8 элементов — это и есть Capacity. Вот вам код для демонстрации:
Тот, который вернет, и будет считаться найденным элементом. ![]() "Равномерность" — это, грубо говоря, разбиение массива на промежутки, где каждый промежуток назначается определенному хэшу: скажем, с первого по десятый элементы массива будут хранить объекты с хэшем 45678. С одиннадцатого по двадцатый — зарезервированы для элементов с хэшем 45679 и т.д. Кстати, к слову о емкости коллекции: в приведенном примере словарь для хранения использует массив из двадцати элементов — это его емкость, а храниться в нем могут на данный момент только Саша и Маша: Count == 2.
0
|
||||||||||||
|
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
|
||
| 28.11.2016, 20:16 | ||
|
а вообще словари очень быстрые, собственно нет ничего быстрей поиска по ключу в словаре, каким-то образом даже двоичный поиск сдает позиции против обычного Dictionary(я раньше думал что там и есть двоичный поиск), возможно как раз группировки имеют в этому отношение даже если хранить там сотни тысяч записей поиск укладывается в несколько миллисекунд, какими там органами измерить )
0
|
||
|
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
|
||
| 28.11.2016, 22:56 | ||
|
0
|
||
|
1 / 1 / 2
Регистрация: 25.08.2012
Сообщений: 108
|
|||
| 28.11.2016, 23:45 [ТС] | |||
|
К примеру есть такой словарь mydictionary: 1000-Маша 1001-Саша->1001-Коля 1002-Вася 1003-Петя 1. Для того что бы найти обьект "Коля" мы берем метод - mydictionary.ContainsKey("Коля"); 2. В этот момент словарь берет этот передаваемый параметр "Коля" высчитывает хеш для этого значения. Результат - 1001. 3. Затем как Вы сказали словарь должен найти группу, в которой находиться это значение. Для того что бы найти эту группу необходимо сравнивать наш хеш 1001 с остальными ключами в словаре, правильно? В нашем случае к примеру будет так: a)Сравнение нашего хеша 1001 с первым элементом в словаре, который содержит значение "Маша". В этом случае ключ "Маша" возвращает хеш 1000. Хеши не равны. 1001!=1000. б) Словарь переходит к следующему элементу. Вычисляет хеш элемента "Саша". Он будет равен 1001. Затем он сравнивает искомый хеш с текущим элементом. 1001==1001. Ага, хеш коды совпали, значит нашли нужный список. Далее с помощью метода Equals он сравнивает ключи. Но они не равны. Искомый у нас "Коля" а текущий "Саша". В итоге он начинает двигаться по линейному списку, переходя к следующему элементу, и находит ключ "Коля". Правильно? Добавлено через 19 минут
0
|
|||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||
| 29.11.2016, 02:43 | ||
|
На основании сгенерированного хэша словарь высчитывает место нужной корзины за О(1), безо всяких итераций. Ну например у вас массив из n корзин. Примитивнейший способ нахождения нужной корзины — это взять сгенерированный хэш и найти остаток от деления его на количество корзин (n) — вы сразу же получите местоположение нужной корзины, без итераций. Разумеется, такой способ может генерировать много коллизий (и генерирует, если GetHashCode плохо реализован), потому на деле там может быть довольно мохнатый матан, но суть в том, что местоположение корзины высчитывается по формуле, без обхода по всем корзинам.
1
|
||
|
1 / 1 / 2
Регистрация: 25.08.2012
Сообщений: 108
|
||
| 29.11.2016, 17:12 [ТС] | ||
|
0
|
||
|
Почетный модератор
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
|
||
| 30.11.2016, 14:58 | ||
|
kolorotur, поясните пожалуйста следующий момент.
Продолжая пример уважаемого Olejan_one: В данном словаре: 1) Сначала перейти к линейному массиву совпавших хэшей за одну итерацию. 2) Затем, убедившись, что в нулевом элементе массива неверное значение, начать перебирать массив дальше и во второй итерации, вызвав Equals(Коля) для уже первого элемента массива, обнаружить совпадение.
0
|
||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||
| 30.11.2016, 15:31 | ||
|
В конкретном примере для нахождения Коли потребуется три действия: 1. Высчитывание хэша для Коли = 1001 2. Проверка Саша.Equals(Коля) -> false 3. Проверка Коля.Equals(Коля) -> true Получается, что если хранить в словаре объекты с одинаковыми хэшами, то сложность поиска будет как в обычном массиве: O(n).
1
|
||
|
|
|
| 09.12.2016, 07:37 | |
|
Еще иногда проще использовать табличный метод
0
|
|
| 09.12.2016, 07:37 | |
|
Помогаю со студенческими работами здесь
20
Программирование без использования встроенных функций matlaba
Программирование условных переходов. Как обойтись без условных переходов? Как можно сделать без условных операторов? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Символьное дифференцирование
igorrr37 13.02.2026
/ *
Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет
значение производной при заданном х
Логарифм записывается как: (x-2)log(x^2+2) -. . .
|
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
|
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу,
и светлой Луне.
В мире
покоя нет
и люди
не могут жить в тишине.
А жить им немного лет.
|
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила»
«Время-Деньги»
«Деньги -Пуля»
|
|
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога
Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
|
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога
Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
|
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога
Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
|
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
|