Вопрос № 181127: Здравствуйте, уважаемые эксперты! Прошу Вас помочь в решении следующей задачи: Разработать подпрограмму, которая подсчитывает, сколько раз за- данный символ встречается в строке. Разработать программу, которая вводит с клавиатуры строку и чи...
Вопрос № 181127:
Здравствуйте, уважаемые эксперты! Прошу Вас помочь в решении следующей задачи: Разработать подпрограмму, которая подсчитывает, сколько раз за- данный символ встречается в строке. Разработать программу, которая вводит с клавиатуры строку и число N и выдаёт список символов, которые встречаются в строке не менее N раз.
Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, Ivan Afonin! Вот и программа. Единственный момент, на который хочу обратить внимание: Подпрограмма analize, которая считает вхождения символа в строке, портит строку - прописывает на всех последующих местах, где находит данный символ, ноль. Это сделано с целью избежать повторного анализа данного символа. 181127-block-sch.doc (41.0 кб)
Код:
;Разработать подпрограмму, которая подсчитывает, сколько раз за- ;данный символ встречается в строке. Разработать программу, которая ;вводит с клавиатуры строку и число 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 ;вводим строку
l
ea 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 sto
i_next ;были только разделители - на продолжение ; иначе - конец числа и выходим stoi_eol: ; если числа нет и встретили 0dh -
конец строки mov ax, bx ;число возвращаем в ax ret stoi endp
code ends end start
----- Люби своего ближнего, как самого себя
Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 07.12.2010, 03:25
Номер ответа: 264558 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru
Оценка ответа: 5 Комментарий к оценке: Все замечательно! :)
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 264558
на номер 1151 (Россия) |
Еще номера »
Оценить выпуск »
Нам очень важно Ваше мнение об этом выпуске рассылки!
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.