Помощь - Поиск - Пользователи - Календарь
Полная версия: Подключение мыши
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Страницы: 1, 2
Бродяжник
И еще есть замечания по рекурсии.
Во-первых, что делает переменная flag? Ведь на участке между
flag := false
и
if not flNoWord and not flag then
значение flag не меняется. Поэтому фактически это условие сводится к
if not flNoWord
. Во-вторых, как должна работать рекурсия? У нас должна быть возможность вернуться назад на любое число шагов. Например, первые 5 гнезд заполнились нормально. А шестое мы так и не смогли заполнить. Мы возвращаемся назад на один шаг. Это значит, что последнее вписанное слово нужно вычеркнуть из сетки. То есть либо необходим специальный алгоритм вычеркивания, либо нужно сохранить предыдущую копию. Допустим, у нас есть копия. Но вот беда - оказывается, что другого варианта заполнения пятого гнезда нет. Это значит, что надо вернуться еще на шаг назад и вычеркнуть из сетки еще и четвертое слово. То есть нужна еще одна копия - и не одна, а весь набор промежуточных копий для всех шагов. Если мощь компьютера позволяет, можно и так. А если нет? Тогда нужно изобретать специальный алгоритм вычеркивания. Почему специальный? Потому что он должен учитывать то, что буква в сетке может принадлежать не одному, а сразу двум словам. И вычеркивать ее нужно с оглядкой.
Еще один вариант сводится к тому, чтобы в специальном стеке хранить все вписываемые в сетку буквы, а также те символы, которые были в сетке до этого вписывания. Например, пересекаются слова "кот" и "сон". При выписывании слова "кот", в стек попадают:
к (пробел)
о (пробел)
т (пробел)
При вписывании слова "сон":
с (пробел)
о о
н (пробел)
Теперь при вычеркивании слова "сон" на место букв "с" и "н" будут вписаны пробелы, а вместо "о" опять "о", которое и останется там, если не будет вычеркнуто слово "кот".
Ведь сейчас что получается? Допустим, пятое слово пересекается с четвертым и шестым. Мы заполнили шесть гнезд, дошли до седьмого. С седьмым ничего не вышло, с шестым и пятым тоже, пришлось вернуться к четвертому слову. Мы меняем четвертое слово и снова беремся за пятое. Вызываем для него ARBEIT. Входим в ARBEIT и заново определяем маску пятого слова (и это правильно). И в эту маску попадают буквы из нового четвертого слова, а также - внимание! - из уже отвергнутого шестого (оно ведь все-таки было вписано в сетку!).
LOVE133
после многочисленных тестов пришла к выводу что рекурсия плохая и не работает ))) (*тихонько сходит с ума*). Работает только в одну сторону с перебором словаря и просто проверкой , подходит , не подходит...
но ничего путного придумать не могу, потому как не хватате глубоко понимания сущности рекурсии...
если хранить маску слов на всех этапах, то не хватит никакой памяти... Однокурсник использует деревья и списки, остался последний день, не думаю, что успею переделать все ))
Бродяжник
Я уже почти заставил его работать, хотя тут, конечно, всплыли новые приколы. Например, может случиться так, что есть четыре первых гнезда. При этом первые три не пересекаются друг с другом, а четвертое пересекается с первым и со вторым. Мы заполнили три первых, перешли к четветрому, а с ним не стряслось. И происходит что: мы возвращаемся к третьему, меняем в нем слово - и это никак не влияет на ситуацию с четвертым гнездом. Мы прокручиваем все варианты для третьего гнезда, и только потом переходим ко второму и что-то в нем меняем. И это может продолжаться весьма долго...
но зато у меня уже заполнился вот такой кроссворд:
.О.В.
АДАЗА
.Ё.В.
АЖГОН
.А.Д.


Еще бы узнать, что такое АЖГОН и АДАЗА...
Бродяжник
Оно работает!
Это еще актуально?
LOVE133
Конечно актуально ))) допуск до экзамена )) тут не только такие приколы выплыли.. почти половина моей работы напрасна, при чем так что выть хочется... Сделала мышь, чтоб удобнее было, теперь надо клавиатуру подключать, интерфейс плохой. проверка неправильная.Теперь надо не только проверить можно ли составить кроссворд, но и пользователю показать , что так делать нельзя, то есть если он уже забил слово, то сделать так , чтоб ы восседние клеточки и кликнуть-то нельзя было, то есть показать, куда можно кликать а куда нет, вообщем полный провал ... сколько глюков будет, я уже чувствую...
Бродяжник
Ладно, кладу то, что пока есть.
Те несколько кроссвордов, которые я пробовал, заполнились.
Единственное, что:
- я так и понял, что с проверкой что-то неладно, поэтому я ее просто отключил;
- процесс рекурсии может быть длительным. При этом желательно брать такую сетку, чтобы в ней был минимум горизонтальных слов. Например, кроссворд в виде буквы Ш строится на ура, а вот в виде Е не так быстро. Если хотите порадоваться, задайте сетку в виде квадрата
*****
*...*
*...*
*...*
*****

- словарь полон всяких загадочных слов типа "аак" или "абаза". Ну, тут мы не виноваты...
Итак, вот исходник.
(У меня буквы в графическом режиме выводятся нормально. Если у вас - нет, поэкспериментируйте со шрифтами).
LOVE133
пасибо вам огроменно , не знаю, что б я делала ))) все работает на ура, и даже если где-то выяснится что не на ура, то наверно не расстроюсь, теперь остался интерфейс. но тут как-нибудь постараюсь справиться... теперь вот придется думать над проверками, где можно клутку ставить , а где нет ... начинаю трассировать программу. так графика подвисает после очередного прерывания и ничего сделать не могу. потому как мышь пропадает, поэтому и проверить сложно , где что не работает.
Бродяжник
Хорошо!
С интерфейсом Вы справитесь, Вы жутко способная. smile.gif
А я пойду почивать на лаврах.
Удачи!
LOVE133
Вчера докрутила, перестала мышь работать... не работает на весь экран в программе, то есть на полэкрана работает, а на вторую половину никак.Самое интересное. что запускаешь оригинал, на работает, запускаешь похожую программу, с теми же процедурами - работает . И если оригинал запустить после копии, то он тоже начинает работать, а ошибку найти не могу, ничего вроде не меняла.Может подскажете, где косяк?
Бродяжник
unsure.gif У мя все работает... и причин ему не работать не видно...
А вообще ничего, ничего, проект развивается!
(А заставка, кстати, была неплохая...)
LOVE133
надеюсь - это окончательный вариант... Только есть еще несколько вопросов по процедурам в программе. Если можно, прокомментируйте несколько процедур, как именно они работают, файл Komment.pas . У меня обнаружилось несколько непоняток в связи с неполадками в работе )))
1) словарь просматривается от начала до конца только один раз? или по кругу?
2) в случае ситуации, когда нельзя составить кроссворд в принципе, что будет в этом случае, зависнет?
3) пару раз выводил на экран кроссворд, в котором одно и тоже слово встречалось 3 раза )))
и еще.. проверку на правильность ввода при самом вводе сетки мне милостиво разрешили не делать, но заставили выводить где именно ошибся пользователь.Так как у меня процедура SELECTED заполнения идет через repeat , то там очень сложно что-то поменять так , что б и смысл соранился и что-то можно было вывести... я думала о полной перерисовке экрана, то есть если есть 4 клетки вместе, то выделить их все , елси есть одна стоящая одиноко. выделить и ее, а потом спросить перерисовать сетку или нет.
это конечно все мелочи, меня волнуют больше всего комментарии , отчет писать надо будет )
Бродяжник
Read this.
LOVE133
Volvo , очень прошу вас прокомментировать код... потому как самой не осилить ну никак, как не старалась.Так как писала не я и процедура рекурсивная то и трассировать очень сложно, не все понимаю , как работает.А спрашивать будут...
program IncMassive;

type

setArray = array[1..10, 1..10] of integer;

var

a,b:setarray;

i,j:integer;

n:integer;


procedure print(const a: setarray);

var i, j: integer;

begin

writeln;

for i := 1 to n do begin

for j := 1 to n do write(a[i,j]:3);

writeln;

end;

end;


procedure increm(i_start, j_start: integer;

n: integer; value: integer; var a: setarray);

begin

a[i_start, j_start] := value;


if (i_start > 1) and (a[i_start - 1, j_start] > value)

then increm(i_start - 1, j_start, n, value + 1, a);


if (i_start < n) and (a[i_start + 1, j_start] > value)

then increm(i_start + 1, j_start, n, value + 1, a);


if (j_start > 1) and (a[i_start, j_start - 1] > value)

then increm(i_start, j_start - 1, n, value + 1, a);


if (j_start < n) and (a[i_start, j_start + 1] > value)

then increm(i_start, j_start + 1, n, value + 1, a);

end;



begin

randomize;

write('input N:'); readln(n);


for i := 1 to n do

for j := 1 to n do a[i, j] := random(2);


print(a);


b := a;

for i := 1 to n do

for j := 1 to n do

if b[i, j] = 1 then inc(b[i, j], n*n);


for i := 1 to n do

for j := 1 to n do

if b[i, j] = n*n + 1 then Increm(i, j, n, 2, b);


for i := 1 to n do

for j := 1 to n do

if b[i, j] <> 0 then dec(b[i, j]);


print(b);

readln;

end.
pascal65536
Извините, что вмешиваюсь.
Просто Вы затронули интересную тему - составление кроссворда.
Я тоже бился над этой задачей, лет несколько тому назад.
Если интересно, то с удовольствием поделюсь опытом.
Очень мне словарь Ваш понравился. Я свой создавал сам, ещё до того как смог впервые выйти в интернет.
Пришлось написать спец. утилитку - "выдиратель" слов из текста, причем тех, в которых нет ничего, кроме букв русского алфавита (в Вашем словаре есть слова с дефисами это слово ведь не годится для кроссворда)
Потом возникла проблема отделения имён существительных в ед.числе им.падеже от всех остальных, тогда пришлось написать ещё одну программку, которая по окончанию определяла нужное это слово или нет. Набор неверных окончаний хранился в отдельном файле.
Сетку для кроссворда "рисовал" в текстовом редакторе, из звёздочек и пробелов. Мыши на моём компьютере по моему не было тогда, или я просто не решался её подключать.
И полным перебором всех слов сетка заполнялась. Правда не все сетки ей были по зубам, на этом я собственно и остановился.
Ещё пару слов про словарь. Слова были разбиты по длине, и хранились в отдельных файлах. 02, 03 ... 24
Длиннее 24 букв слов в орфографическом словаре нет, да и вряд ли его придётся использовать.
При такой системе хранения, отпадала проблема отбрасывания "коротких" или "длинных" слов. Файл делался короче, примерно, в 10 раз и работать с ним было намного легче. По крайней мере отбрасывалась как минимум одна проверка на совпадение длины.
LOVE133
Я с удовольчствием рассмотрю все предложения ))) Когда я бралась за эту задачу. я не думала, что все будет настолько сложно и запутанно. Утром доделала заполнение сетки, теперь начались проблемы с рекурсией.
Дело в том , что в программе используется массив USED - использованные ранее подошедшие и не подошедшие слова. То есть , если словарь хотя бы 4000 слов, то на каком-то шаге рекурсии , его весь нужно загнать в этот массви, джля того чтобы определить подходит слово или его надо удалить на этом шаге, но в паскале это возможно только с помощью динамической памяти... вот тут я и села. ТО есть программа до ходит да максимального размера массива использованных слов, а дальше проверка , было слово или нет просто станвовится бесполезной. ведь массив кончился и ничего туда больше не записывается. тут образуется зацикливание, вроде до конца файла еще не дошли, и слова уже все подряд подходят и рекурсия дальше не идет .... что тут делать?
Бродяжник
Love133
Если потерпите, завтра выложу версию с продвинутым словарем, поддерживающим запоминание до 32000 слов и ускоренный поиск слова заданной длины.
pascal65536
Привет соратникам! smile.gif
GoodWind
тут вот какая мысль возникла... а ведь большинство слов в получившемся кроссворде нвчинаются на первые 3-4 буквы алфавита...
LOVE133
а потому словарь отсортирован по алфавиту и длине слов. в начале самые длинные, и гнезда сортируются так же, то есть берем первое подходящее слово ( а оно в начале алфавита smile.gif ) и идем дальше и так до упора. Если не прокатило, берем второе подходящее слово - все из того же словаря , значит отличаться они будут максимумна 2-3 буквы )))) Попробовала работать с динамической памятью... Косяков немеряно, память толком выгрузить не могу.... но работает вернее...

Конечно потерплю )) деваться все равно некуда, сдавать-то надо....
pascal65536
GoodWind
Это поначалу так, что слова начинаются на одинаковые буквы, потом, когда кроссворд достроится до конца, окажется, что буквы-то разные. Первое слово берётся из алфавитного списка, а все оставльные подбираются по маске.
LOVE133
Paskal , как там насчет наработок ? мне было бы интересно посмотреть на ваш вариант обработки словаря и перебор, потому как дымаю полным перебором все это дело решилось бы быстрее раза в 3 )))
pascal65536
LOVE133
Думаете, быстрее? Нифига подобного. СтОит подумать над другим алгоритмом, отличным от полного перебора.
А исходник выложу у себя на сайте, сюда линк выложу. Думаю, администраторы не обидятся.
Бродяжник
Oops...
Зашился я с работой, так что не до кроссвордов. Видимо, я выбываю из игры...
В общем, идея была такая - хранить в массиве использованных слов не сами слова, а номера соответствующих записей в файле словаря. Тогда имеем всего два байта на слово, за счет чего размер массива можно существенно растянуть. Для этого, правда, пришлось сконвертировать словарь из текстового в типизированный файл. Начерно я это реализовал, оно даже работает, хотя одну не очень большую сетку ковыряло с полчаса. (А все из-за того, что слова на i-том и i+1-м уровне рекурсии оказались не связанными друг с другом). Но к "передаче в эксплуатацию" не готово.
mega_chok.gif
LOVE133
давайте хоть черновик )))как-нибудь доковыряю, смысл в принципе понятный, а до ума доведу как-нибудь, потому что в том виде, что у меня сейчас точно не примут )) просто на каком-то месте зацикливается и дальше не строит и сообщение о том что построить нельзя не выводит, поэтому и не принимают ... а косяки подправлю ))
pascal65536
Выкладываю исходник, для общего ознакомления.
Только, пожалуйста, не надо его массово распространять.
Дата создания многих файлов - август 1999 года, так что прошу не судить строго, за корявый местами код.
findword.zip 322кБ Ссылка будет актуальна до июня.
В архиве есть всё, о чем я писал. Сетка кроссворда в файле setka.txt
Бродяжник
Вот.
Читайте ReadMe.txt
Может, стоит подумать над тем, чтобы как-то отображать на экране процесс поиска, чтобы пользователь не скучал, и не думал, что все повисло? Хотя в графическом режиме это будет давать лишние тормоза...
LOVE133
Пасибки огромное ))) потихоньку разбераюсь, все равно торопиться уже некуда , только сдать осталось . Может , все таки доделаю, как положено )))
Бродяжник
Удачи!
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.