Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.11.2011, 17:31   #1
Maksimall89
Пользователь
 
Аватар для Maksimall89
 
Регистрация: 10.11.2010
Сообщений: 59
Восклицание Нахождение моды в массиве.

Надо написать программу которая находит моду в массиве чисел т.е. надо найти число которое встречается больше всего раз в массиве, если таких чисел несколько вывести любое из них, реализовать в связке pas-asm. Нельзя использовать больше 1 массива.
Я по пытался это написать вроде в td всё работает хорошо, но не возвращает значение max обратно в pascal. Не могу найти ошибку.

Алгоритм мой заключаетсяв том, что я сравниваю smax и max в которые я записываю значения массива.
Т.е. при первом проходе в max - 1 значение элемента массива, если оно встретилось там раз 5, тогда maxn=5; А в smax значение 2 элемента (ну или 1 это не важно), если оно встретилось 4 раза, тогда smaxn=4. Так-как smax встретилось большое количество раз, тогда заменяю max на smax и smax заношу следующие значение элемента массива.. Если нет, тогда лишь в smax заношу следующие значение элемента массива. При следующем проходе у меня в max уже хранится smax, а в smax следующие значение элемента массива, и я снова сравниваю, что чаще встретится в smaxn и maxn хранится сколько раз я его встретил.
Я бы его сделал легче, просто мне нельзя использовать 2 массив, только 1.
А 30 раз ходит внешний цикл, чтобы двигать smax.
А во внутреннем цикле идет подсчет сколько встретилось раз max и smax
Пишу в связке tp 7.0 + tasm.
Код:
    {$L LAB2.obj}
    uses crt;
    const n=30;
    type mas=array[0..n] of integer;
    var
       a:mas;
       i,max: integer;
    { объявляю процедуру}
    procedure LAB2(var max:integer;var a:mas ); external;
    {начало бреда}
    begin
    clrscr;
    randomize;
    write('Исходный массив:');
    for i:=0 to n do
        begin
             a[i]:=random(n);
             write(a[i],', ');
        end;
    writeln;
    lab2(max,a);{вызываем asm}
    writeln('Чащё всего встречается число ',max);
    readkey;
    end.
Код:
    .286
            public  LAB2
    data    segment public
     maxn   dw      ?
     max    dw      ?
     smax   dw      ?
     smaxn  dw      ?
    data    ends
    code    segment byte public
    assume  cs:code, ds:data
    ;start
    LAB2    proc near
        push bp
        mov  bp,sp
        pusha
            ;загружаем массив и максимум
            lds ax,[bp+8] ;max
            lds bx,[bp+4] ;массив
     
            xor dx, dx
            xor si, si ;чистим
            xor di, di
            ;задаем начальные значения для сравнения
            mov cx, [bx]
            mov max, cx
            mov smax, cx
            mov dx, bx
    ;1 цикл
    mov cx, 1Eh ;заполняем счётчик цикла
            push bx;сохраняем значение ах до входа в под.цикл
    mainn:
            push bx
            push cx
            mov cx, 1Eh  ;запуск первого под цикла
            mov bx,dx    ;начинаем цикл с 1 элемента
    addl:
            mov si,max
            cmp [bx],si
            je imax
            mov di,smax
            cmp [bx],di
            je ismax
            ;ходим по внтуренниму массиву
            add bx,2
            loop addl
            ;начинаем сравнение
    iff:
            mov si,max
            mov di,smax
            cmp si,di
            jl yesmen ;если меньше то идем туда, если нет то
            mov si,0
            mov maxn,si
            mov smaxn,si
            mov si,[bx]
            mov smax,si
    endd:
    pop cx ;восстанавливаю внешний счетчик (самый главный)
    pop bx  
    add bx,2 ;сдвиг на следующий элемент массива
    loop mainn
    jmp mainend  
    ;инструментируем счетчики количества повторений цифр    s
    imax:  inc maxn
               loop addl
    ismax:  inc smaxn
                    test cx, cx
                    jz endd
                    loop addl
    yesmen:
                    mov si,max ;меняю местами max=smax
                    mov di,smax
                    mov si,di
                    mov max,si
                    mov maxn,0
                    mov smaxn,0
                    mov si,[bx]
                    mov smax,si
                    jmp endd
    mainend:
    ;вывод
            mov bx, max
            mov bx, 0Ah
            lds si, [bp+8]
            mov [si],bx
            popa
        pop bp
        ret 8
    LAB2 endp
    code ends
         end LAB2
Maksimall89 вне форума Ответить с цитированием
Старый 15.11.2011, 19:35   #2
Karpinsky
Подтвердите свой е-майл
 
Регистрация: 19.10.2011
Сообщений: 28
По умолчанию

Maksimall89, смотри:

Основная программа - почти та же, что и у тебя:
Код:
uses crt;

const
   n = 30;
type
   mas = array[0 .. n] of integer;

{$L LAB2.obj}
procedure findproc(sz: integer; var max : integer;
          var a : mas ); far; external;

var
   a : mas;
   i, max : integer;

begin
   clrscr;
   randomize;
   write('Исходный массив:');
   for i := 0 to n do
   begin
      a[i]:=random(n);
      write(a[i],', ');
   end;
   writeln;

   findproc(n + 1, max, a);

   writeln('Чащё всего встречается число ',max);
   readkey;
end.
А вот ассемблерная часть делается гораздо проще:
Код:
.model large, pascal
.code

; процедура принимает 3 параметра (размер массива,
; Var-параметр, через который вернется значение, и сам массив)
; Заодно сделаем сохранение всех используемых регистров.
; TASM затолкает их в стек и вытащит перед выполнением RET.

; Вся игра с
; push bp
; mov  bp,sp
; ...
; pop bp
; ret 8
; тоже не нужна. Указываем соглашение вызовов PASCAL, и TASM
; делает всю "грязную" работу самостоятельно...

findproc proc far uses es ax bx cx dx, sz:word, max:dword, a:dword
	public findproc

	mov bx, 0	; Здесь будет храниться мода
	mov cx, sz
	les di, a
	
outer_loop:
	push cx
	
	les si, a
	mov ax, word ptr es:[di]
	xor dx, dx	; счетчик повторений текущего элемента
	mov cx, sz
inner_loop:
	cmp ax, word ptr es:[si]
	jne no_good
	inc dx
no_good:
	add si, 2
	loop inner_loop
	
	cmp bx, dx ; новый счетчик больше старого максимума?
	jg no_op
	mov bx, dx ; значит, у нас есть новый кандидат на "моду"
	les si, max
	mov word ptr es:[si], ax ; сохраняем текущее значение моды в "max"
no_op:
	add di, 2 ; переходим к следующему элементу	
	pop cx
	loop outer_loop
	
	ret	
findproc endp
end
Вот и всё...
Karpinsky вне форума Ответить с цитированием
Старый 15.11.2011, 20:00   #3
Maksimall89
Пользователь
 
Аватар для Maksimall89
 
Регистрация: 10.11.2010
Сообщений: 59
По умолчанию

Karpinsky, большое спасибо!
Maksimall89 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Нахождение максимума в массиве AnderoN Помощь студентам 4 12.07.2011 13:24
C++ нахождение максимума в Массиве frixer Помощь студентам 4 10.03.2011 17:05
Нахождение серии в массиве akialex Помощь студентам 5 25.11.2009 18:28
нахождение произведения в массиве Sonyalex90 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 10 11.10.2009 13:08
нахождение min в массиве jenja Общие вопросы C/C++ 2 04.10.2008 19:32