Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Алгоритмы > Поиск слов для игры "Балда" |
Автор: Superklug 6.2.2007, 10:06 |
Дорый день. ![]() Я думаю все знакомы с этой игрой в слова, поэтому в подробности вдаваться не буду. Есть поле размером 5x5 клеток. В некоторых клетках стоят буквы. Необходимо составить все возможные на этом поле слова. В принципе я уже все сам написал, но алгоритм слишком медленно работает. Если есть какие-нибудь мысли, пишите. Заранее спасибо! P.S. Если надо, могу описать свой алгоритм. |
Автор: nini 6.2.2007, 11:30 |
Привет, Давай алгоритм в общих чертах ![]() Мож слишком много вложенных циклов взял? Чего-ниб по экспоненте =)?, поэтому и медленный... |
Автор: Strannik 6.2.2007, 11:38 |
А как слова могут быть расположены на этом квадрате? Если словарь большой, то основное время уходит на поиск слова в словаре. Попробуй организовать словарь как хэш-таблицу... Тогда время обращения в среднем (при хорошей хэш-функции) будет О(1). |
Автор: _Evrey_ 7.2.2007, 10:30 |
Есть исходники данной игры написанна на Делфи, скорость заполнения всего поля 5 Х 5 при словаре 9237 слов примерно 2 минуты 5 секунд, начальное слово парта.... вот ссылка на http://slil.ru/23887538 . Когда в нее играли победить ее было непросто, если честно играть... |
Автор: nerezus 7.2.2007, 14:50 |
я бы делл так: составляется словарь, сортируется цикл по х: цикл по у: рекурсивный перебор по направлениям(верх, них, лево, право) до тех пор, пока начало слова есть в словаре. |
Автор: nerezus 7.2.2007, 19:18 | ||
|
Автор: _Evrey_ 8.2.2007, 07:12 | ||||||
Если посчитать сложность алоритма то самая длинная операция в этой игре проход по словарю т.к. он должен быть большой. В связи с этим необходимо ограничить проход по словарю. Смысл победы в этой игре заключается в том что нужно найти как можно больше слово и вписать его в ячейки, поэтому словарь нужно сортировать именно по количеству букв в слове т.е. "Пороход" "снаряд" "парта" "нора" "кот" так будут сначала подбираться большие слова, потом мальнькие...
В том архиве есть мой словарь, в принципе с ним уже трудно играть...
Задержки замедлят алгоритм, а так лучше всего поиск выделить в отдельный поток, или если пишешь под Borland Builder то поставь в начале цикла Application->ProcessMessages(). |
Автор: Superklug 8.2.2007, 11:00 | ||||
Это понятно... Дело в том, что мне нужно найти все возможные слова, а не самое длинное. А слова точно нужно в таком порядке располагать. (например если на поле всего 7 символов, то не имеет смысла искать среди слов из 9 символов)
![]() |
Автор: _Evrey_ 8.2.2007, 15:04 | ||||
Ну это немного другая задача... Вот набрасал быстро код на c++ Builder выполняет то что тебе нужно, из текущего состояния выберает все слова которые подходят... Будет что-то непонятно по коду, спрашивай отвечу... Данный кусок кода выводит все найденные слова в компонент TListBox1 на форме... Данный код не оптимальный и возможно имеет ошибки, особо не проверял но работает быстро...
|
Автор: SelenIT 8.2.2007, 19:29 |
Имхо, для уменьшения числа переборов нужно отсекать пути с невозможными сочетаниями букв (типа "ЪЩ" или "ОЬ") до любых обращений к словарю. AFAIK, на списках таких исключений работают автопереключалки раскладки клавиатуры (типа PuntoSwitcher), из какой-нибудь из них и можно "выдрать" такой список... |
Автор: Superklug 9.2.2007, 17:36 | ||||||||
Да есть ошибки ![]() Например: Зачем нужно использовать try и catch? Еще не понятно зачем ты делал вот это
И следовательно вот такие вещи
Вобщем-то идея у меня такая же. Проверять подходят ли начало и конец слова. Но есть и отличая, например я это проверяю не для всех пустых клеток, а только для соседних. И еще я не все слова из словаря перебираю, а только те, длина которых меньше или равна количеству букв на поле +1. Большое тебе спасибо ![]()
Это если сначала составлять комбинации, а затем искать по ним слова в словаре. Я сейчас по другому делаю. Перебираю слова из словаря и проверяю можно ли их вписать на данное поле. (так быстрее получается даже с моим словарем) |
Автор: _Evrey_ 9.2.2007, 19:57 | ||
В принципе правильно ![]() try, catch - для отлова ошибок, в начале когда писал выходил за границы массивов и строк, вываливалось исключение, которое в этом блоке отлавливал... a[i][j] = String(word[k]); Это у меня такой стиль програмирования, иногда сталкивался с проблемой что компилятор при компилировании кода переводил цифры в ASCII символы, подразумевая что у меня там используется тип char.... for(ai=0;ai<5;ai++) for(aj=0;aj<5;aj++) temp[ai][aj] = a[ai][aj]; Так сохранял массив, потом его востанавливал, необходимо для того чтобы поле после подстановки букв имело первоначальный вид... |
Автор: Superklug 10.2.2007, 01:16 | ||
Я имел ввиду, что это в принципе не нужно. Т.е. не надо подставлять буквы. Ты ведь добавляешь в массив pr 1 - этого достаточно. У меня вопрос ![]() Помнишь ты говорил, про Application->ProcessMessages()? Так вот это не совсем то, что мне нужно. Мне нужно, чтобы можно было отменить процесс поиска. Как это сделать? |
Автор: Anikmar 10.2.2007, 01:20 | ||
Имеется в виду поиск в БД? А какая БД используется? |
Автор: Superklug 10.2.2007, 01:51 |
Нет, БД не использую. Может быть и нужно, но я не умею... ![]() P.S. Что-то мы не в той теме об этом говорим... |
Автор: Anikmar 10.2.2007, 02:03 | ||||
Вам уже был совет, поэтому я уточнил.
Пользуйтесь вышеприведенным советом. В процессе поиска опрашиваете некий внешний раздражитель (нажатие на клавишу, мышьку, щелчок на кнопке) - если случилось прерывайте поиск. Опрашивать следует в самом внутреннем цикле. |
Автор: _Evrey_ 10.2.2007, 17:50 | ||
Для того чтобы предотвратить цикл необходимо выставить глобальную переменную, и в цикле проверять, если значение изменилось то выход, например...
Проверять выход лучше всего вначале цикла.. |
Автор: Toska 27.10.2007, 19:56 |
тут были выложены исходники.... ссылка устарела :wack выложите пожалуйста снова ![]() |