| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Алгоритмы > выборка чисел |
| Автор: oleg1973 6.2.2004, 21:35 |
| кароче есть массивчик на примерно 500.000 елементов нада создать другой в котором будут все элементы встречаюсиеся в первом (тоесть без повторений) написал я но работает секунд 40 на р4 2000 делаю так к примеру начальный массив А конечный В, С счетчик елементов в массиве В беру елемент из А сравниваю с В стока раз скока С (чтоб весь массив не пробегать ) ну и так далее поражает медленность работы идеи есть? |
| Автор: December 6.2.2004, 23:08 |
| oleg1973 Давай чуть подробнее, по-русски. |
| Автор: bagira 6.2.2004, 23:24 |
| А элементы какого типа - числа или строки? |
| Автор: acp 6.2.2004, 23:31 | ||
А разница? 2 oleg1973 Исключающая сортировка |
| Автор: bagira 7.2.2004, 00:04 |
| Я когда-то делала подобную вещь с массивами чисел. Сортировала по возрастанию (не важно как), а потом перебирала элементы и счетчик добавлялся, когда одна группа одинаковых чисел сменяла другую. (это все равно, что строить гистограмму). А в принципе, для сортировки не важно, какой тип... |
| Автор: Дрон 7.2.2004, 13:08 | ||
| Вот придумал небольшой алгоритм, который работает гораздо быстрее описанного тобой. Будут вопросы -- спрашивай. Написан на Борланд C++
|
| Автор: Дрон 7.2.2004, 13:22 |
| Одно важное замечание к работе данного алгоритма: Исходный массив должен содержать случайную последовательность чисел, если же она отсортирована (или близка к этому), тогда всё -- дас ист капут Сожрёт полгига памяти и будет очень долго думать. Так уж он устроен. |
| Автор: Дрон 7.2.2004, 13:50 | ||||||||
| Это опять я. Немножко подумал и вот о чём С прошлым моим замечанием можно хорошо бороться, если оптимизировать выбор начального элемента, т.е. значение числа v. Например вот так: заменить строку
и ещё заменить
Тем самым начальный элемент будет выбираться из середины массива, что позволит избежать некоторых нерпияных эффектов. А вообще лучший выбор -- элемент ближайший к среднему арифметическому всех элементов массива, но чего-то сходу мне не придумать как это реализовать. |
| Автор: oleg1973 7.2.2004, 13:56 |
| December ну я имел ввиду из массива выбрать уникальные числа тоесть если к примеру в массиве А число 2 встречается 100 раз то в массив В мы засунем всего одну 2 а не 100 ну не знаю я как точнее обяснить |
| Автор: Sardar 7.2.2004, 16:37 |
| Что ты точно знаешь об этом массиве(остортирован, где то предсказуем...)? Основная работа это поиск уже добавленных элементов. Сильно ускорить поиск можно используя хеширование, т.е. тебе надо написать HashSet(хешированное множество). В зависимости от размера ковши также могут быть хешированны. Дугой способ - отсортированые многослойные связанные списки. Это реализовать чуть сложнее. Многослойные это значит, что ты имеешь не только ссылки на обеих соседей, но и на другие(каждый пятый, одинадцатый...) элементы. Благодаря многослойности можно быстро передвигатся по списку. Так как это связанный список, тебе дешево вставлять в любое место новые элементы, т.е. держать список отсортированным. Так как список отсортирован ты можешь использовать бинарный поиск. Ну а дальше ищем, если нет элемента, то вставляем его в список. Для большей инфы иди на http://algolist.manual.ru. |
| Автор: oleg1973 7.2.2004, 17:35 |
| Sardar массив не отсортирован и абсолютно рандомный |
| Автор: Дрон 7.2.2004, 18:00 |
| Э-э... А что моя идея не подходит? |
| Автор: Sardar 7.2.2004, 19:33 | ||||
Ну тогда хеш-множество или сортированные многослойные связанные списки. Что это я написал выше.
Дрон по моему ты привел код быстрой сортировки... |
| Автор: Дрон 7.2.2004, 19:40 | ||
И да, и нет. Я использовал идею похожую на быструю сортировку. Но только похожую. Вы бы посмотрели результат работы. Она выдаёт "почти отсортированный" по убыванию массив. Но это не сортировка, а именно решение задачи, поставленной oleg1973. Проверьте. Я не говорю, что это оптимальное решение. Но ведь оно работает. Причём очень быстро. Эти 500000 элементов обрабатываются за доли секунды. Что ещё надо? |
| Автор: remax 8.2.2004, 18:54 | ||||
2 aсp
Например, если данные имеют целочисленный тип и количество возможных комбинаций значений существенно меньше, чем оговоренные в условии 500000, то можно применить следующий алгоритм.
Достоинства метода: 1.нет вложенных циклов и рекурсий 2.не важно в каком порядке встречаются данные. 3.в результате мы знаем не только какие значения элементов были в исходном массиве но и сколько раз 4.результирующий массив отсортирован (либо по возрастанию либо по убыванию) Ограничения. 1.Очень эффективен, если исходный массив имеет тип byte. Имеет смысл, если исходный массив имеет тип ShortInt или Word. Не приколен, если исходный тип Longint. Недопустим для вещественных типов данных. 2.тип элементов массива ar1 выбирается так, чтобы в одном элементе поместилось общее число элементов исходного массива ar0. |
| Автор: remax 8.2.2004, 19:17 |
| В принципе, алгоритм можно переделать таким образом, что ar1 - array of boolean. Тогда на втором этапе надо делать не Inc, а присвоение True. При этом - метод теряет достоинство №3 (см. предыдущий топик) но уходит ограничение 2. Кроме того, более мягкие требования к занимаемой памяти масивом ar1. P.S. Эту идую можно развить и дальше - использовать одно битные значения, тогда каждый элемент массива ar1 будет содержать 8 флагов наличия соответствующих значений. Но в этом случае в 2-3 раза уменьшиться общее быстродействие метода. |
| Автор: December 8.2.2004, 23:59 | ||
Чё надо сделать - я понял, ты перечитай как ты объясняешь свой метод - это даже не по-русски |
| Автор: Guest 9.2.2004, 00:15 | ||||||||
тут действительно так и просится устроить сортировку только нужно выбрать сортировку время работы которой росло бы со скоростью меньше n*n (иначе можно простым перебором)
за критерий разделения массива на две части можно выбрать не значение элемента, а его индекс: делим массив на две половинки (первые 25000 и вторые 25000), сортируем их отдельно, а потом объединяем их если не ошибаюсь, это называется "метод слияния" время его работы и количество необходимой памяти зависит только от длины входного массива вот, как это может выглядеть на C++:
тестировал я его на SIZE 16, вроде бы правильно работает в таком виде он работает только, если SIZE - степень 2, его, конечно, можно как-нибудь приспособить к другим SIZE, но это уже не очень интересная задача, можно просто дополнять массив до нужного количества одним из его элементов: на результат это не повлияет, а время сильно не изменится... |
| Автор: maxim1000 9.2.2004, 00:17 |
| это был я... |