Консультация № 181127
06.12.2010, 17:11
100.00 руб.
0 2 1
Здравствуйте, уважаемые эксперты! Прошу Вас помочь в решении следующей задачи:
Разработать подпрограмму, которая подсчитывает, сколько раз за-
данный символ встречается в строке. Разработать программу, которая
вводит с клавиатуры строку и число N и выдаёт список символов, которые
встречаются в строке не менее N раз.

Для решения использовать Tasm, операционная система ДОС, формат ЕХЕ. По возможности приложите к решению блок-схему. Задача взята из Программирование на Ассемблере для персональных компьютеров: учебно-методическое пособие (стр. 59, вар. 8).
Спасибо

Обсуждение

давно
Посетитель
7438
7205
07.12.2010, 03:25
общий
это ответ
Здравствуйте, Ivan Afonin!
Вот и программа.
Единственный момент, на который хочу обратить внимание:
Подпрограмма analize, которая считает вхождения символа в строке,
портит строку - прописывает на всех последующих местах, где находит данный
символ, ноль. Это сделано с целью избежать повторного анализа данного символа.
181127-block-sch.doc (41.0 кб)
[code h=200];Разработать подпрограмму, которая подсчитывает, сколько раз за-
;данный символ встречается в строке. Разработать программу, которая
;вводит с клавиатуры строку и число N и выдаёт список символов, которые
;встречаются в строке не менее N раз.

data segment para public 'data'
sNum db 'Enter N: $'
sString db 0ah,'Enter string: $'
sResult db 0ah,'Symbols: $'

;буфер для ввода числовой строки (для функции 0ah)
bNum db ? ;максимальный размер буфера
bCount db ? ;реальный размер строки
sBuf db 80 dup (?) ;сама строка
N dw ? ;"водораздел" количества символов
data ends

assume cs:code, ds:data, es:data
code segment para public 'code'
start:
mov ax, data
mov ds, ax
mov es, ax ;пусть es=ds=data

lea dx, sNum
mov ah, 9
int 21h ;ждем число N

mov bNum, 80 ;задаем максимальное значение строки
lea dx, bNum
mov ah, 0ah
int 21h ;вводим числовую строку

lea si, sBuf ;строка
call stoi ;преобразовываем в число
mov N, ax ;сохраним

lea dx, sString
mov ah, 9
int 21h ;ждем строку

lea dx, bNum
mov ah, 0ah
int 21h ;вводим строку

lea dx, sResult
mov ah, 9
int 21h ;выведем сообщение о результате

;формируем результат
lea si, sBuf ;адрес строки
xor cx, cx
mov cl, bCount ;длика строки
mov dx, cx ;сохраним для дальнейшего использования
AnalizeLoop: ;по всем символам строки
lodsb ;читаем al=ds:[si], si=si+1
cmp al, 0 ;0 помечается обработанный символ
je AnalizeNext ;обходим
call Analize ;считаем
cmp ax, N ;сравниваем с N
jc AnalizeNext ;если меньше, то обходим
mov al, [si-1] ;читаем заново символ
int 29h ;выводим
AnalizeNext:
loop AnalizeLoop ;по всем

mov ah, 0
int 16h ;ждем нажатия на клавишу

mov ax, 4c00h
int 21h ;выход в ДОС

Analize proc ;считаем вхожения символа в al в строку sBuf
push cx ;сохраним счетчик прохождения по строке
lea di, sBuf ;адрес строки
mov cx, dx ;длина
xor bx, bx ;счетчик
AnLoop:
scasb ;сравниваем al с es:[di], di=di+1
jne AnNext ;не равно - на следующий
test bx, bx ;проверим - первый найденный?
jz IncCnt ;если первый, то на инкремент количества
mov byte ptr [di-1], 0 ;все последующие обнуляем, чтобы не повторяться
IncCnt:
inc bx ;считаем
AnNext:
loop AnLoop
mov ax, bx ;найденное количество
pop cx
ret
Analize endp

stoi proc ;преобразование строки [si] в число AX
xor bx, bx ;здесь будем стоить число
xor cx, cx ;счетчик разрядов
stoi_next:
lodsb ;очередной символ
cmp al, 0dh ;конец стоки?
je stoi_eol
cmp al, '0'
jb stoi_sep ;любая нецифра - разделитель
cmp al, '9'
ja stoi_sep
push ax ;сохраним новый разряд
mov ax, 10
mul bx ;умножим старшие на 10
pop dx ;новый
and dx, 0fh ;'0'-'9' -> 0-9
add ax, dx ;добавляем новый разряд
mov bx, ax ;сохраняем
inc cx ;считаем
jmp stoi_next ;продолжаем
stoi_sep: ;встретили разделитель
jcxz stoi_next ;были только разделители - на продолжение
; иначе - конец числа и выходим
stoi_eol: ; если числа нет и встретили 0dh - конец строки
mov ax, bx ;число возвращаем в ax
ret
stoi endp

code ends
end start[/code]
5
Все замечательно! :)
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
08.12.2010, 01:28
общий
Подправил, добавил блок-схему
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа