|
|
|
Поиск одинаковых элементов
|
|||
|---|---|---|---|
|
#18+
Задача: Есть массив элементов, нужно максимально быстро определить есть ли в нем повторяющиеся элементы. Решение которое напрашивается сразу: Брать каждый элемент и сравнивать его с впереди стоящими, до тех пор пока не найдем равные или не дойдем до последнего. Итого придется сделать до n*(n-1)/2 сравнений. Внимание, уважаемые знатоки, вопрос: Это самый эффективный алгоритм? или есть лучше (если вообще существуют)? Например, решение, которое напрашивается не стразу : Прозводим сортировку массива, а далее сравниваем лишь соседние элементы. Итого, если будем использовать QSort, мы можем получить O(n*log n)*(n-1), т.е. O(n^2 * log n), а в худшем случае так вообще O(n^3). Вроде бы не лучше, но ведь можно модернизировать сортировку под наши цели, а также оптимизировать ее с учетом того, что известна некоторая статистическая информация о входных данных. Более конкретная постановка задачи: проверяем корректность одного FAT сектора OLE2 контейнера ( WindowsCompoundBinaryFileFormatSpecification.pdf ). Такой сектор зачастую состоит из 128 DWORD'ов. Они зачастую располагаются возрастающими цепочками: 1h, 2h, 3h, ...., 12h. Между цепочками могут быть значения DWORD(-1), DWORD(-2), DWORD(-3) или DWORD(-4), которые вполне легально могут повторяться, остальные значения повторяться не могут. Итак, повторю, надо максимально быстро проверить, что нет повторяющихся значений, кроме "легальных". Важен сам факт повтора, позиция и значение узнавать не обязательно. Вот такая вот задачка, прошу помощи =) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.02.2009, 02:22:07 |
|
||
|
Поиск одинаковых элементов
|
|||
|---|---|---|---|
|
#18+
авторЕсть массив элементов, нужно максимально быстро определить есть ли в нем повторяющиеся элементы. смотря какой разброс диапазон значений массива, если малый, то начинаешь пробего с первого элемента и складируешь элементы в множество, и смотришь, имеется ли данный во множестве. если да, то значит хотя бы один да уже есть и ты на нем находишься. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.02.2009, 03:52:17 |
|
||
|
Поиск одинаковых элементов
|
|||
|---|---|---|---|
|
#18+
сортировка log(n)*n + пробег по соседним значениям n = (1 + log(n))*n 4 8 15 16 23 42 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.02.2009, 09:08:31 |
|
||
|
Поиск одинаковых элементов
|
|||
|---|---|---|---|
|
#18+
W_and_GПрозводим сортировку массива, а далее сравниваем лишь соседние элементы. Итого, если будем использовать QSort, мы можем получить O(n*log n)*(n-1), т.е. O(n^2 * log n), а в худшем случае так вообще O(n^3). Вроде бы не лучше, но ведь можно модернизировать сортировку под наши цели, а также оптимизировать ее с учетом того, что известна некоторая статистическая информация о входных данных. Нет же. Сортировка и сравнение - два последовательных этапа, их сложности складываются, O(n*log(n)) "съедает" O(n-1), так что никакого куба не будет, Aklin J прав. Подозреваю, что это наиболее оптимальный вариант. Только если нужна гарантированная (а не средняя) скорость, то не QSort, конечно, а что-нибудь типа пирамидальной сортировки нужно использовать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.02.2009, 11:29:31 |
|
||
|
Поиск одинаковых элементов
|
|||
|---|---|---|---|
|
#18+
Спасибо за идею про множества, правда там разброс все же большой, но помница большие множества частенько на бинарных деревьях делают, это можно как-нибудь использовать. А после того как посмотрел сюда: http://ru.wikipedia.org/wiki/Пирамидальная_сортировка, то окончательно убедился, что вариант с деревьями возможно будет наилучшим. Всем отписавшимся спасибо! =) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.02.2009, 23:20:39 |
|
||
|
Поиск одинаковых элементов
|
|||
|---|---|---|---|
|
#18+
мне кажется задачу возможно решить за 1 проход по массиву элементов без сортировки следующим образом: создаем массив возможных значений DWORD ( к сожалению не знаю типа данных) например для двухбайтных элементов это будет массив 0 ... 65655 для однобайтных массив 0...255 условно назовем флагов ( биты ) просматривая исходный массив по значению элемента исходного массива лезем в массив флагов если флаг =0 ставим его в 1 если флаг уже = 1 то фиксируем повтор элементов в принципе в массив флагов можно писать не значение DWORD, а некую функцию от него ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.02.2009, 15:15:39 |
|
||
|
Поиск одинаковых элементов
|
|||
|---|---|---|---|
|
#18+
Valerсоздаем массив возможных значений DWORD ( к сожалению не знаю типа данных) например для двухбайтных элементов это будет массив 0 ... 65655 для однобайтных массив 0...255 условно назовем флагов ( биты ) просматривая исходный массив по значению элемента исходного массива лезем в массив флагов если флаг =0 ставим его в 1 если флаг уже = 1 то фиксируем повтор элементов делал нечто подобное когда-то, когда нужно было определить. есть ли в FAT перекрёстные ссылки. в принципе работает, и нужен всего 1 проход. но если разброс большой, то нужно много памяти, т.к. размер массива равен кол-ву элементов / 8 так, посчитал, для 320 ГБ винта нужно всего-лишь 10 метров памяти - не так и много а для перебора 4-байтных значений - пол гигабайта - многовато P.S. 2Valer - в DWORD 65536 помещается, а не 65656 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.02.2009, 18:14:49 |
|
||
|
Поиск одинаковых элементов
|
|||
|---|---|---|---|
|
#18+
Valerв принципе в массив флагов можно писать не значение DWORD, а некую функцию от неговот этого не понял, поэтому добавлю от себя создаётся обнулённый массив битов, значение элемента равно номеру бита ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.02.2009, 18:17:06 |
|
||
|
Поиск одинаковых элементов
|
|||
|---|---|---|---|
|
#18+
Курить в сторону Хеш-функций. Смысл - из одного массива создается несколько маленьких. Одинаковые значения гарантированно лежат в одном подмассиве ( хеш функция однозначна в прямом направлении ). Стоимость в идеале: Подсчет хеш - n ( 1 проход ), проход - (1+log(n/m))*n/m где m - число подмножеств. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.02.2009, 22:00:36 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=35813854&tid=1344665]: |
0ms |
get settings: |
8ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
34ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
49ms |
get tp. blocked users: |
1ms |
| others: | 208ms |
| total: | 334ms |

| 0 / 0 |
