WEB форумы на jedi
[Форум] [Помощь] [Поиск] [Выйти]
Добро пожаловать, [info]User

WEB форумы на jedi [ПОИСК] [Архив до 03.2006]

Тема Срочно нужна помощь!!! К предыдущему сообщению На следующее сообщение Взаимопомощь

Отправил DDDa в 10:50 25.05.2000[Ответить]
Срочно нужна помощь!!!

Требуется помочь найти ошибку в алгоритме, реализованном на С++ 3.1 для доса. Алгоритм простой, но никак не могу найти, почему не работает (вернее работает но не совсем так как надо, хотя при ручном просчете на бумаге все получается). Алгоритм из 4 вложенных циклов и 2 условий.

ДИПЛОМ ГОРИТ !!!

Сдавать через неделю, а я уже две недели на одном месте топчусь и все никак не идет...

P.S. Пиво за мной!!! даже скорее всего не только пиво...


Отправил KSM в 14:10 25.05.2000[Ответить]
Кидай код прямо в форум. Здесь и обсудим. Может кто еще присоединится.

PS А трассировать ты пробовал.


Отправил DDDa в 14:35 25.05.2000[Ответить]
Так там кода примерно 16 к. а вот глючит скорее всего одна процедура. Замечен такой глюк :
for ()
if (a!=0) label=a;
else return.

Так вот при трассировке обнаруживается, что на n-om шаге при а==0 условие оказывается верным (???) и выполняется код label=a, причем label становится равным 12.

Как такое могет быть - никак не пойму.
Может еще где глючит...
Так объяснять неудобно. Вот встретиться бы и на месе поэкспериментировать...


Отправил CAHbKA в 15:02 25.05.2000[Ответить]
это значит на работу с памятью надо смотреть.
чтоб не было выше по тексту вещей вроде
char *a; без дальнейших malloc или new (и free)
и если = переопределен, то и на него посмотреть.
а кусок выглядит так, что идет работа c неинициализированной label (вне функции)


Отправил CAHbKA в 15:11 25.05.2000[Ответить]
тогда кидай код в инкоминг а сюда ссылку. наверное код то не секретный ?;)


Отправил DDDa в 15:36 25.05.2000[Ответить]
Код не секретный, просто тк это отладочный вариант, то там много лишнего, проше встретиться и на месте показать что для чего, и где не работает.

Были проблемы с выделением памяти (просто стояла опция automatic far data), и память выделялясь с глюками. Но потом память под массивы (их там 4 по 64000 unsigned char) стал выделяеть динамически (farcalloc). Проверили по адресации блоки выделенные под массивы не перекрываются.

= не перепределялся.
label описана как unsigned char label; в начале процедуры.


Отправил DDDa в 15:47 25.05.2000[Ответить]
Файл лежит в инкаминге

DDDa2All.rar

Глючит (скорее всего) функция conflict();
В main-е цикл с кучей if-ов, который размечает скопления точек на картинке метками. Но получаются соприкасающиеся области с разными метками. conflict ищет такие области и заменяет одну метку на другую. Confliсt вызывается из while до тех пор пока не кончатся конфликты. В теории должны остаться несколько несоприкасающихся областей точек, которые помечены разными метками. Но conflict либо зацикливается, либо начинает объединять физически не соприкасающиеся области.

Примерно так.
P.S. неудобно объяснять дистанционно.
pPicture - картинка (состоит из двух цветов 0 и 240)
LPicture - массив меток.


Отправил CAHbKA в 16:01 25.05.2000[Ответить]
уже видно, что при первом проходе будет обращение за пределы массива на 1 элемент... LPicture[64000-(l-1)*Nj+(k-1)] /l=1 и k=1/

и кстати дальше там идет присвоение этого же значения переменным
а, в С, насколько помню, элементы нумеруются с 0.

и сразу дальше
LPicture[64000-(a-1)*Nj+(b-1)]=conl1;
при первом проходе a=1 и b=1, т.е. пишем вне массива

и сразу дальше
правильно будет проверить результат farmalloc

и еще, я бы посмотрел на прототипы farmalloc и FP_* что-то мне говорит, что они с указателями far работают...


Отправил DDDa в 17:08 25.05.2000[Ответить]
LPicture[64000-(l-1)*Nj+(k-1)] /l=1 и k=1/ тут да, забыл скобки добавить
LPicture[64000-((l-1)*Nj+(k-1))]

>и кстати дальше там идет присвоение этого же значения переменным
>а, в С, насколько помню, элементы нумеруются с 0.

не совсем понял...

про a и b - тоже скобки. (просто пытался немного переделать алгоритм и недосмотрел)

про farmaloc: смотрел при отладке указатели так они указывают на последовательные участки памяти по объему чуть больше чем нужно под массив (на сколько помню сдвиг на мини параграф).


Отправил CAHbKA в 17:21 25.05.2000[Ответить]
когда l=1 и k=1 получается LPicture[64000]
а последний элемент массива LPicture[63999]
и дальше при a=1 и b=1
с LPicture[64000-(a-1)*Nj+(b-1)]=conl1 тоже самое
скобки на сложение 0+0 не повлияют


Отправил DDDa в 17:30 25.05.2000[Ответить]
За границу вроде больше не выходит.
Но, все равно не работает, так как размечает одной меткой области, которые физически не соприкасаются. То есть при сравнении соседних точек (3х3) умудряется соединить области, отстоящие др от др на несколько десятков точек...

исправленный cpp лежит в инкаминге
rasp4_.cpp


Отправил CAHbKA в 18:30 25.05.2000[Ответить]
if ( (LPicture[(l)*Nj+(k)]!=0) && (LPicture[(i-1)*Nj+(j-1)]!=LPicture[(l)*Nj+(k)]))


это видимо , вторая часть выражения
поскольку l=i-1 и k=j-1 (получаетя && A!=A)
т.е. будет if(1 && 0) вообще не будет работать




(поправлено)


Отправил DDDa в 19:48 25.05.2000[Ответить]
Попытаюсь объяснить:
Первоначально имеем двух цветную (0 и 240) картинку. Необходимо пометить отдельно стоящие скопления точек разными метками.
000
011
001
Тк картинка bmp и выводится снизу слева, то поиск новой области для точки (2,2) ведем по точкам (1,3)(1,2)(2,3). Если это нули, как для точки (2,2), то считаем что это новая область и обозначаем точку (2,2) новой меткой. Если же одна из этих точек уже имеет какую нибудь метку, то точке (2,2) присваиваем метку одного из соседей. Проверются только три соседние точки потому, что точки сверху и справа от центральной еще не имеют меток.

Далее необходимо объединить соприкасающиеся области
000
010
220

для точки с меткой 1(то есть центральной) смотрим соседние точки. Если соседняя точка 0 (то есть фон) ничего не делаем.
Если соседняя точка не 0, то проверяем не равна ли она центральной точке. Если равна, то ичего не делаем. Если же соседняя точка не равна центральной, то значит нашли две соприкасающиеся зоны помеченные разными метками.А тк соприкасающиеся зоны являются одним оъектом, то данные области сливаются путем замены одной из конфликтующих меток на вторую.
Процедура повторяется для всех точек массива.
В результате в идеальном случае получаем набор областей помеченных одной меткой, причем области изолированы др от др нулями. Причем изолированные области не могут иметь одинаковой метки, тк считаются разными объектами.

Вот это и требуется сделать.
Исходные данные:
unsigned char PPicture[64000]; // Картинка (два цвета)
unsigned char LPicture[64000]; // Массив меток.
первоначально
setmem(LPicture, 64000, 0);

У меня проблема в том, что при выполнении алгоритма во время второго этапа каким то образом изолированные области получают одну и ту же метку.
Немного подправил, так теперь не все области объединяет...


Отправил CAHbKA в 18:44 25.05.2000[Ответить]
я не совсем понял, что собственно делается ?
если в поле 3х3 больше одной цветной точки, то что ?


Отправил DDDa в 11:42 26.05.2000[Ответить]
АУ?


Отправил DDDa в 15:49 25.05.2000[Ответить]
Может проще встретиться?


Отправил KSM в 11:43 26.05.2000[Ответить]
Можно и встретится.
И совет: обрати внимание на строку label=label+1; можеш получить не то что хочеш, т.к. + работает как присвоение строк. т.е. если label=1 +1, то будет 11 а не 2; бывает такая фишка проходит.


Отправил DDDa в 12:02 26.05.2000[Ответить]
нет, тут все нормально , тк при проверке выдает что label=1,2,...,14.
То есть меняется с шагом 1.
А если встретиться то где?


Отправил DDDa в 12:17 26.05.2000[Ответить]
Может у тебя ася есть?
Моя 35897833


Отправил KSM в 07:30 29.05.2000[Ответить]
Извини DDDa, что долго не отвечал. Аси у меня нет и несобираюсь ставить. Надеюсь, что с программой справишся самостоятельно, потомушто встретится неудасться, т.к. завалился работой.


Отправил DDDa в 09:53 29.05.2000[Ответить]
Спасибо, тем кто откликнулся.

Тема закрыта!


Отправил CAHbKA в 11:06 29.05.2000[Ответить]
так ты опубликуй правильный выриант :)
и данные исходные и готорвые тоже :))

а то пришлось дома ставить С, вспоминать... :)))


Отправил DDDa в 10:55 01.06.2000[Ответить]
Все таки глюк был в выходе за границу массива.
Если интересно, то исправленную и дополненную версию могу положить в инкаминг.
Вот только что-то я до фтп достучаться не могу :(
говорит что нет такого сервака...


Отправил CAHbKA в 13:17 01.06.2000[Ответить]
положи, интересно. фтп отвечает. ftp://ftp.kosnet.ru


Отправил DDDa в 21:31 01.06.2000[Ответить]
Ну, ежли интересно, то лежит сдесь. Сыровато правда. Но ежли в аспирантуру пойду - наверно лучше получится...
ftp://ftp.kosnet.ru/pub/incoming/end.zip