Консультация № 180574
05.11.2010, 05:16
0.00 руб.
0 3 1
Помогите.
В матрице C[1..N,1..M] целых чисел определить, есть ли “седловая” точка (“седлом” называется элемент матрицы, минимальный в строке, и, одновременно, максимальный в столбце). Если такой элемент есть, вывести значение и его индексы.

исходные данные в файлике pas, сортировка в файлике obj

Обсуждение

давно
Посетитель
7438
7205
05.11.2010, 09:22
общий
Так понимаю, необходимо написать отдельный модуль на ассемблере,
который будет вызываться из программы на Паскале и искать "седловую точку".
Правильно?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
05.11.2010, 19:48
общий
Адресаты:
правильно.
давно
Старший Модератор
31795
6196
10.11.2010, 14:58
общий
это ответ
Здравствуйте, Посетитель - 342589!

Код программы на Pascal:
[code h=100]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{проверяем условие}
if 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.[/code]

Код программы на ассемблере:
[code h=100]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 = dword 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[/code]
Проверялось с помощью ТР7.0 и TASM 2.0.
Программа создает массив с помощью генератора случайных чисел. Проверяется этот массив с помощью контрольной функции написанной на паскале и функции написаной на ассемблере. Т.к. вероятность создания нужного массива очень мала, то "седло" создается принудительно с элементами в строке/столбце равными: 10,9,8. После этого производится аналогичная проверка двумя функциями.
Функции производят поиск первой седловой точки в массиве и выводят об этом сообщение. Остальные точки игнорируются.
вопросы по коду задавайте в мини-форуме.
Удачи!
5
спасибо.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Форма ответа