Бракозябр
Гость
|
|
« : 01-05-2007 14:26 » |
|
Здравствуйте!!! У меня в общем вопрос. Никак вот не могу придумать алгоритм для решения задачи((( Есть массив, заполненный литерами, скажем размером в 100 элементов. Как мне оставить литеры, которые входят один раз? Была идейка - ввести новый массив из 256 элементов-счетчиков каждого элемента, и далее выводить те литеры, которые повторяются один раз, а литеры, повторяющиеся несколько раз, пускать еще на одну обработку. Но нужен другой алгоритм (увы, так сложилось). Помогите советом пожайлуста.
|
|
|
Записан
|
|
|
|
Scorp__)
Молодой специалист
Offline
Пол:
|
|
« Ответ #1 : 01-05-2007 14:59 » |
|
Бракозябр, нет памяти, значит надо тратить процессорное время. Считываем первый элемент и просматриваем массив на предмет совпадений. Совпадений нет - в массив результатов, есть - к следующему элементу. Считываем очередной элемент, повторяем процесс и так до конца массива.
Два цикла один в другом + массив результатов.
|
|
|
Записан
|
- А Вы сами-то верите в привидения? - Конечно, нет, - ответил лектор и медленно растаял в воздухе.
|
|
|
Бракозябр
Гость
|
|
« Ответ #2 : 01-05-2007 15:06 » |
|
Спасибо, Scorp__) ))))
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #3 : 01-05-2007 17:51 » |
|
Если хотим выигрыш и по скорости, и при этом не важно первоначальное состояние массива. Можно сделать сортировку, а потом просто пройтись по отсортированному массиву.
Только естественно сортировка не должна быть пузырьком, иначе выигрыша в скорости не будет.
|
|
« Последнее редактирование: 01-05-2007 17:59 от Finch »
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Scorp__)
Молодой специалист
Offline
Пол:
|
|
« Ответ #4 : 01-05-2007 19:48 » |
|
Finch, хорошее дополнение. Выигрыш получится O(log(n) + n) против O(n^2). Если я ничего не напутал.
|
|
« Последнее редактирование: 01-05-2007 19:54 от Scorp__) »
|
Записан
|
- А Вы сами-то верите в привидения? - Конечно, нет, - ответил лектор и медленно растаял в воздухе.
|
|
|
Serg79
|
|
« Ответ #5 : 03-05-2007 04:51 » |
|
Только естественно сортировка не должна быть пузырьком, иначе выигрыша в скорости не будет.
Кстати, при размере массива в 100 элементов, пузырьковая сорнтровка не проигрывает по своему быстродействию с быстрой.
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #6 : 03-05-2007 12:21 » |
|
Serg79, Я думаю, что 800 проходов при сортировке против 10000 есть разница. Другое дело, что при таком размере массива и при таких скоростях это не столь сушественно. А почему не пузырёк. потому что при проходе пузырьком по массиву мы получим примерно такой же расход времени, который получается в алгоритме указанном Scorp__)
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Sla
|
|
« Ответ #7 : 03-05-2007 13:40 » |
|
если массив "литерный", то можно попытаться построить разреженый массив каждую "литеру" на свое место в массиве типа заполняем arraySort нулями затем цикл по литерному массиву arraySort[ord(mass[i])]:=1; индекс arraySort код "литеры"
|
|
« Последнее редактирование: 03-05-2007 14:01 от Sla »
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Vlaor
Гость
|
|
« Ответ #8 : 04-05-2007 15:32 » |
|
Была идейка - ввести новый массив из 256 элементов-счетчиков каждого элемента, и далее выводить те литеры, которые повторяются один раз, а литеры, повторяющиеся несколько раз, пускать еще на одну обработку..
Что-то я не понял, зачем создавать массив счетчиков если необходимо лишь определить двойное вхождение элемента. Для этого достаточно одного бита на элемент?
|
|
|
Записан
|
|
|
|
Бракозябр
Гость
|
|
« Ответ #9 : 10-05-2007 17:41 » |
|
Уважаемый Vlaor, просто я посчитал в начале сделать алгоритм меньшей сложности и додумался только до массива счетчиков. Ведь нужен был алгоритм с малой сложностью. Если не вру с массивом счетчиков она линейная (прошу палками не бить, плохо пока в это разбираюсь). Но, увы, алгоритм пришлось поменять на более жесткий в плане сложности. В ответ хочу задать вопрос (просто не совсем понял): "Для этого достаточно одного бита на элемент?" Расскажите подробней)))
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #10 : 10-05-2007 17:46 » |
|
Бракозябр, Vlaor имеет в виду битовый массив вместо массива счётчиков ) Быстродействие чуть пониже, но памяти на такий "массив флажков" уйдёт в 8 раз меньше. А счётчики там считают от 0 до 1 , но для этой задачи этого вполне достаточно
индекс бита вычислять так - номер байта == N/8 номер бита в байте == N%8 (маска == (1<<N%8))
|
|
« Последнее редактирование: 10-05-2007 17:49 от Алексей1153++ »
|
Записан
|
|
|
|
Starech
Гость
|
|
« Ответ #11 : 11-02-2008 23:09 » |
|
А не проще: взять первый элемент искать схожие в массиве и если таковые есть удалять вместе с этим элементом, в конце останутся только нужные!
|
|
|
Записан
|
|
|
|
Starech
Гость
|
|
« Ответ #12 : 11-02-2008 23:10 » |
|
Блин забыл, взять второй элемент... третий...
|
|
|
Записан
|
|
|
|
Sands
Помогающий
Offline
|
|
« Ответ #13 : 12-02-2008 10:45 » |
|
Starech А чем предложенній тобой алгоритм лучше предложенного изначально Scorp_)-ом?
|
|
|
Записан
|
|
|
|
Starech
Гость
|
|
« Ответ #14 : 12-02-2008 21:44 » |
|
Примерно одно и то же, но второй массив создавать не обязательно, для ответа... А честно прочитал и пропустил, надо было только дополнить!
|
|
|
Записан
|
|
|
|
Starech
Гость
|
|
« Ответ #15 : 16-02-2008 23:19 » |
|
После завершения программы в BH находиться кол-во оставшихся эл-тов, а в BUFFER сам массив эл-тов, затирки ненужных байтов нет, поэтому при просмотре в отладчике там по всему якобы "массиву" разбросаны эл-ты бывшего массива поэтому и надо было в BH оставлять кол-во оставшихся эл-тов!
START: lea di,BUFFER mov bh,100 ; кол-во эл-тов mov bl,1 ; проверяемый эл-т xor ch,ch
CIKL_1: lea di,BUFFER xor ah,ah mov al,bl add di,ax mov cl,bh jcxz EXIT_PR ; выходим если эл-тов не осталось sub cl,bl ; кол-во проверяемых эл-тов jc EXIT_PR ; выходим если проверяемый эл-т = кол-ву оставшихся mov al,[di-1] ; байт для проверки push di cld repne scasb ; ищем подобный jnz SL_EL dec di mov dx,di ; сохраняем di в dx pop di ; востанавливаем начальное значение push cx ; сохраняем cx mov si,di inc si ; mov cl,bh sub cl,bl rep movsb ; сдвигаем весь массив на байт dec bh ; массив уменьшился pop cx mov di,dx jmp DALEE ; переход на вторую процедуру
; вторая часть программы
OSN_CIKL: repne scasb ; ищем подобный элемент jnz CIKL_1 ; нет, переходим к следующему элементу ; mov dx,di
DALEE: push di mov si,di ; копируем его в si и dx
CIKL_3: jcxz EXIT_SL ; проверяем на конец массива да! - выходим scasb ; нет проверяем следующий эл-т jnz ROLLING ; не подобный на сдвиг массива inc si ; подобный увеличиваем значение элемента для сдвига dec bh dec cx ; уменьшаем значение счётчика jmp CIKL_3
ROLLING: pop di ; восстанавливаем адрес эл-та куда будем сдвигать push di dec di push cx ; сохраняем счётчик rep movsb ; сдвигаем pop cx pop di jmp OSN_CIKL
EXIT_SL: dec bh ; массив на один эл-т уменьшился! pop di jmp CIKL_1
SL_EL: pop di inc di inc bl ; следующий элемент jmp CIKL_1
EXIT_PR: ret ; здесь может находиться процедура вывода на монитор
BUFFER db 1, 8 dup 17, 38, 17, 20 dup 7, 69 dup (?) CODESG ends end
Честно говоря фигни наворотил... наверно...
|
|
|
Записан
|
|
|
|
|