Хостинг портала RFpro.ru: Московский хостер Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64 РАССЫЛКИ ПОРТАЛА RFPRO.RU Лучшие эксперты данной рассылки Номер выпуска: | 1382 | Дата выхода: | 13.11.2010, 14:00 | Администратор рассылки: | Лысков Игорь Витальевич (Старший модератор) | Подписчиков / экспертов: | 224 / 66 | Вопросов / ответов: | 2 / 2 | Вопрос № 180574: Помогите. В матрице C[1..N,1..M] целых чисел определить, есть ли “седловая” точка (“седлом” называется элемент матрицы, минимальный в строке, и, одновременно, максимальный в столбце). Если такой элемент есть, вывести значение и его индексы. Вопрос № 180612: Добрый день! Подскажите, как можно обработать нажатие кнопки «Далее >», чтобы появлялось не MessageBox, как у меня сейчас в программе, а такое же зарегистрированное в WinMain proc окно, но с другим заголовком окна и другим текстом вопроса? Кнопка ... Вопрос № 180574: Помогите. В матрице C[1..N,1..M] целых чисел определить, есть ли “седловая” точка (“седлом” называется элемент матрицы, минимальный в строке, и, одновременно, максимальный в столбце). Если такой элемент есть, вывести значение и его индексы.
исходные данные в файлике pas, сортировка в файлике obj Отправлен: 05.11.2010, 05:16 Вопрос задал: Посетитель - 342589 (Посетитель) Всего ответов: 1 Страница вопроса » Отвечает Зенченко Константин Николаевич (Модератор) : Здравствуйте, Посетитель - 342589!
Код программы на Pascal:
Код: const n=5; m=6; type tMass=array[1..n,1..m]of integer; var c:tMass; i,j:integer; {подгружаем модуль} {$L d:\_cat_xp3\asm_lib\q180574.obj} function sedlo(var a:tMass;var b,c:integer):boolean;external; {контрольная подпрограмма} function Z(var a:tMass;var b,c:integer):boolean; var d,e,f,g:integer; begin for d:=1 to b do begin f:=1; {ищем минимум} for e:=f+1 to c do if a[d,e]<a[d,f] then f:=e; g:=1; for e:=g+1 to b do{проверяем условие} i f a[e,f]>a[g,f] then g:=e; if a[d,f]=a[g,f] then break; end; Z:=a[d,f]=a[g,f]; b:=d; c:=f; end; begin {сбросим генератор случайных чисел и создадим массив} randomize; for i:=1 to n do begin for j:=1 to m do begin c[i,j]:=random(50); write(c[i,j]:3); end; writeln; end; {запускаем проверку массива двумя функциями} i:=n; j:=m; if Z(c,i,j) then writeln('C[',i,',',j,']:=',c[i,j]) else writeln('No'); i:=n; j:=m; if sedlo(c,i,j) then writeln('asm-C[',i,',',j,']:=',c[i,j]) else writeln('asm-No'); {принудительно создаем "седло"} for i:=1 to m do C[4,i]:=10; for i:=1 to n do C[i,3]:=8; C[4,3]:=9; for i:=1 to n do begin for j:=1 to m do write(c[i ,j]:3); writeln; end; {проверка созданой точки} i:=n; j:=m; if Z(c,i,j) then writeln('C[',i,',',j,']:=',c[i,j]) else writeln('No'); i:=n; j:=m; if sedlo(c,i,j) then writeln('asm-C[',i,',',j,']:=',c[i,j]) else writeln('asm-No'); readln; end.
Код программы на ассемблере:
Код: model medium public sedlo .code .186 ; ;function sedlo(var a:tMass;var b,c:integer):boolean; sedlo proc near arg_3 = dword ptr 4 ; j:integer arg_2 = dword ptr 8 ; i:integer arg_1 = dwor d ptr 0Ch ; c:tMass ;создаем стековый кадр push bp mov bp, sp ;загружаем количество строк в массиве les di,[ bp + arg_2 ] mov cx,es:[ di ]; ;загружаем указатель на массив les di,[ bp + arg_1 ] mov si,di mov bx,di ;начинаем цикл поиска isBigLoop: push cx ;загружаем количество элементов в строке les di,[ bp + arg_3 ] mov cx,es:[ di ] ;сбросим указатель и входим в цикл xor di,di jmp isMinBegin ;переходим к следующему проверяемую элементу isMinLoop: add di,2 ;сравниваем элементы cmp ax,es:[ bx + di ] jle isBig; ;запоминаем очередной минимальный элемент isMinBegin: mov ax,es:[ bx + di ] mov dx,di isBig: loop isMinLoop ;запоминаем указатель на столбец и начало строки push dx push bx push es ;устанавливаем указатель на на столбец mov bx,si add bx,dx ;загружаем счетчим цикла les di,[ bp + arg_2 ] mov cx,es:[ di ] ;загружаем и считаем длину строки les di,[ bp + arg_3 ] mov dx,es:[ di ] shl dx,1 ;востанавливаем сегмент массива pop es xor di,di ;цикл проверки "седла" isMaxLoop: cmp ax,es:[ bx + di ] jl isSmall; add di,dx loop isMaxLoop ;нашли "седло" считаем индекс строки pop ax sub ax,si mov cx,dx xor dx,dx div cx ;возвращаем значение inc ax les di,[ bp + arg_2 ] stosw ;считаем столбец и возвращаем значение pop ax shr ax,1 inc ax les di,[ bp + arg_3 ] stosw ;удаляем счетчик основного цикла и возвращаем "ИСТИНУ" pop cx mov ax,1 jmp isExit ;востанавливаем начало строки и переходим к следующей isSmall: pop bx add bx,dx pop dx pop cx loop isBigLoop ;не нашли возвращаем "ЛОЖЬ" xor ax,ax isExit: mov sp,bp pop bp retn 0Ch sedlo endp end Проверялось с помощью ТР7.0 и TASM 2.0. Программа создает массив с помощью генератора случайных чисел. Проверяется этот массив с помощью контрольной функции написанной на паскале и функции написаной на ассемблере. Т.к. вероятность создания нужного массива очень мала, то "седло" создается принудительно с элементами в строке/столбце равными: 10,9,8. После этого производится аналогичная проверка двумя функциями. Функции производят поиск первой седловой точки в массиве и выводят об этом сообщение. Остальные точки игнорируются. вопросы по коду задавайте в мини-форуме. Удачи! ----- Итерация от человека. Рекурсия — от Бога. — Л. Питер Дойч Ответ отправил: Зенченко Константин Николаевич (Модератор) Ответ отправлен: 10.11.2010, 14:58 Номер ответа: 263944 Украина, Киев Тел.: +38-097-238-60-03 Адрес: Украина, Киев
Оценка ответа: 5 Комментарий к оценке: спасибо. Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 263944 на номер 1151 (Россия) | Еще номера » | Вопрос № 180612: Добрый день! Подскажите, как можно обработать нажатие кнопки «Далее >», чтобы появлялось не MessageBox, как у меня сейчас в программе, а такое же зарегистрированное в WinMain proc окно, но с другим заголовком окна и другим текстом вопроса? Кнопка и поле ввода в новом окне остаются прежними. Не знаю, насколько это правильно, но пытался после нажатия кнопки: .IF ax==ButtonID shr eax,16 .IF ax==BN_CLICKED вызвать второе окно с помощью INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName2,\ WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,\ 540,480,NULL,NULL,hInst,NULL но компилятору чем-то не понравился хендл программного модуля hInst, мне пришлось ввести переменную MYhInst dd ? и заменить hInst на MYhInst. Потом создавал на новом окне новую кнопку, текст, поле ввода, заголовок. При работе программы получалось почти всё, кроме текста: во втором окне он был таким же, как и в первом. Вдобавок второе окно перекрывало первое, а мне нужно, чтобы было всегда только одно окно: или первое, или второе, но не оба вместе. Вот как переделать эту нижеприведённую программу? Отправлен: 08.11.2010, 02:43 Вопрос задал: Adsorores (Посетитель) Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич (Старший модератор) : Здравствуйте, Adsorores! Вы избрали порочный путь... 1) У Вас текст вопроса рисуется в общей отработке WM_PAINT, поэтому он будет одинаков во всех окнах 2) Если создаете новое окно, то для него надо создавать свою отработку очереди сообщений. Придется также разграничивать функцию окна... Это все можно сделать, но зачем идти этим путем, зачем усложнять себе жизнь?! Гораздо проще работать в одном окне. Просто рисуем новый вопрос и все! В Вашем случае это можно сделать, например, введя переменную с адресом строки вопроса. И следим, с каким вопросом работаем...
Кстати, переменная hInst действительна только внутри подпрограммы WinMain, Вы же хотели ее использовать внутри WndProc, что, естественно, является ошибкой. Надо было использовать глобальную переменную hInstance
Код: .386 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\gdi32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\gdi32.lib
.data ClassName db "SimpleWinClass",0 AppName1 db "Окно № 1",0 AppName2 db "Окно № 2",0 ; заголовок для второго окна ButtonClassName db "button",0 ButtonText db "Далее >",0 EditClassName db "edit",0
OurText dd OurText1, OurTex t2, OurText3 MAX_IDX equ ($-OurText)/4 - 1
OurText1 db 10,13," Вопрос №1:",0 OurText2 db 10,13," Вопрос №2: ",0 ; текст для второго окна OurText3 db 10,13," Вопрос №3: ",0 ; текст для третьего окна
TestString db " Программа успешно завершена!",0 String db "End",0
.data? hInstance HINSTANCE ? CommandLine LPSTR ? hwndButton HWND ? hwndEdit HWND ?
idxAsk dd ?
buffer db 512 dup(?)
.const COLOR equ COLOR_BTNSHADOW ButtonID equ 1 EditID equ 2
.code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine mov CommandLine,eax invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD LOCAL wc:WNDCLASSEX LOCAL msg:MSG LOCAL hwnd:HWND mov wc.cbSize,SIZEOF WNDC LASSEX mov wc.style,CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground, COLOR+1 mov wc.lpszMenuName,NULL mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc
mov idxAsk, 0
INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName1,\ WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ CW_USEDEFAULT,540,480,NULL,NULL,\ hInst,NULL mov hwnd,eax INVOKE ShowWindow, hwnd,SW_SHOWNORMAL INVOKE UpdateWindow, hwnd .WHILE TRUE INVOKE GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) INVOKE TranslateMessage, ADDR msg INVOKE DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ret WinMain end p
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL hdc:HDC LOCAL ps:PAINTSTRUCT LOCAL rect:RECT
.IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_CREATE invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR EditClassName,NULL,\ WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or\ ES_AUTOHSCROLL,50,50,160,25,\ hWnd,EditID,hInstance,NULL mov hwndEdit,eax invoke SetFocus, hwndEdit invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonText,\ WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\ 95,95,80,25,hWnd,ButtonID,hInstance,NULL mov hwndButton,eax .ELSEIF uMsg==WM_PAINT invoke BeginPaint,hWnd, ADDR ps mov hdc,eax
invoke SetBkMode, hdc, OPAQUE ;зададим тип замещен ия старого содержимого :) invoke GetSysColor, COLOR invoke SetBkColor, hdc, eax
invoke GetClientRect,hWnd, ADDR rect mov ecx, idxAsk invoke DrawText, hdc, OurText[ecx*4], -1, ADDR rect, NULL invoke EndPaint,hWnd, ADDR ps .ELSEIF uMsg==WM_COMMAND mov eax,wParam .IF ax==ButtonID shr eax,16 .IF ax==BN_CLICKED .IF idxAsk < MAX_IDX inc idxAsk invoke InvalidateRect, hWnd, NULL, 0 invoke SetFocus, hwndEdit .ELSE invoke MessageBox,NULL,ADDR TestString,ADDR String,MB_OK invoke SendMessage,hWnd,WM_DESTROY,0,0 .ENDIF .ENDIF .ENDIF .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp end start ----- Люби своего ближнего, как самого себя Ответ отправил: Лысков Игорь Витальевич (Старший модератор) Ответ отправлен: 08.11.2010, 05:13 Номер ответа: 263870 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 263870 на номер 1151 (Россия) | Еще номера » | Оценить выпуск » Нам очень важно Ваше мнение об этом выпуске рассылки! Скажите "спасибо" эксперту, который помог Вам! Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА на короткий номер 1151 (Россия) Номер ответа и конкретный текст СМС указан внизу каждого ответа. Полный список номеров » * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов) ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются. *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании. |
Комментариев нет:
Отправить комментарий