Найти слова, в которых заданный символ встречается наибольшее количество раз - Assembler

Узнай цену своей работы

Формулировка задачи:

Доброе время суток еще раз Нужна помощь в написании программы на Асемблере. Буду благодарен за помощь. Задано символ и текст, слова в котором разделены пробелами и знаками препинания. Разработать программу, которая находит и выводит все слова содержащие заданный символ наибольшее количество раз.

Решение задачи: «Найти слова, в которых заданный символ встречается наибольшее количество раз»

textual
Листинг программы
LOCALS
 
.model small
 
.stack 1000h
 
.data
        ;строка для исследования
        String                  db      'Mateusz Viste writes: DWOL is '
                                db      'a tiny tool that computes and '
                                db      'sends "Wake-on-LAN" packets. '
                                db      'Wake-on-LAN (WOL) is an Ethernet '
                                db      'standard that allows a computer to '
                                db      'be turned on by a network message.', '$'
        Len                     dw      $-String
        ;искомый символ
        Char                    db      'e'
 
        ;символы разделители слов
        DelimChars              db      '.,!?;:"() ', "'"
        LenDelimChars           dw      $-DelimChars
        ;переменные
        CrLf                    db      0Dh, 0Ah, '$'   ;перевод троки
        MaxChars                dw      ?               ;максимальное количество искомых символов в слове
        CountWords              dw      ?       ;общее количество слов
.code
 
main    proc
        mov     ax,     @data
        mov     ds,     ax
 
        lea     si,     String
        mov     cx,     Len
        mov     CountWords,     0
        mov     MaxChars,       1       ;значение не нулевое для того, чтобы
                                        ;при отсутствии символа в строке слова не выводились
        ;пропускаем все разделители
@@WhileDelimiter:
        mov     al,     [si]
        call    IsDelimChar
        cmp     ah,     0
        je      @@NewWord
        inc     si
        loop    @@WhileDelimiter
 
        jcxz    @@Finish        ;если строка закончилась - выйти
        ;найдено новое слово
@@NewWord:
        mov     dx,     0       ;длина очередного слова пока равна 0
        inc     CountWords      ;увеличиваем счётчик слов на 1
        mov     di,     0       ;количество искомых символов в очередном слове
        push    si              ;сохраняем в стеке адрес начала слова
        ;пропускаем все буквы слова до разделителя
@@WhileWord:
        mov     al,     [si]
        call    IsDelimChar
        cmp     ah,     0
        jne     @@Break
        cmp     al,     Char
        jne     @@NextChar
        inc     di
@@NextChar:
        inc     dx              ;увеличиваем длину слова
        inc     si              ;переходим к следующему символу
        loop    @@WhileWord
@@Break:
        push    dx              ;сохраняем в стеке длину слова
        push    di              ;сохраняем в стеке количество искомых символов в слове
        cmp     di,     MaxChars
        jbe     @@Next
        mov     MaxChars,       di
@@Next:
        jcxz    @@Finish
        jmp     @@WhileDelimiter
 
@@Finish:
 
        ;вывод результатов
        ;общее количество слов в строке
 
        mov     cx,     CountWords
@@ShowWords:
        pop     ax
        pop     si
        pop     dx
 
        cmp     ax,     MaxChars
        jne     @@SkipShow
        call    ShowWord
@@SkipShow:
        loop    @@ShowWords
 
 
        mov     ax,     4C00h
        int     21h
main    endp
 
;Определяет, принадлежит ли символ в al разделителям слов
;на входе
; al - символ
;на выходе
; ah -  0 (не разделитель), 1 (разделитель)
IsDelimChar     proc
        mov     ah,     0
        pushf
        push    si
        push    di
        push    cx
        push    es
 
        push    ds
        pop     es
        lea     di,     DelimChars
        mov     cx,     LenDelimChars
        cld
        repne   scasb
        jcxz    @@Skip
        jnz     @@Skip
        mov     ah,     1
@@Skip:
        pop     es
        pop     cx
        pop     di
        pop     si
        popf
        ret
IsDelimChar     endp
 
ShowWord        proc
        push    ax
        push    cx
        mov     ah,     40h
        mov     bx,     1
        mov     cx,     si
        mov     dx,     dx
        int     21h
        mov     al,     ' '
        int     29h
        pop     cx
        pop     ax
        ret
ShowWord        endp
 
end     main

Объяснение кода листинга программы

  1. Создание переменных:
    • String - строка для исследования
    • Len - длина строки
    • Char - искомый символ
    • DelimChars - символы-разделители слов
    • LenDelimChars - длина DelimChars
    • CrLf - перевод строки
    • MaxChars - максимальное количество искомых символов в слове
    • CountWords - общее количество слов
  2. Инициализация сегмента данных и регистров.
  3. Начало цикла, проход по строке:
    • Проверка всех символов строки и определение начала нового слова или его окончания, считывание и сохранение найденных слов и искомых символов.
  4. Поиск длины и количества искомых символов в каждом слове.
  5. Вывод результатов:
    • Вывод всех слов, в которых искомый символ встречается наибольшее количество раз.
    • Завершение программы.

Оцени полезность:

11   голосов , оценка 3.636 из 5
Похожие ответы