Найти и вывести самую длинную цепочку из слов одинаковой длины - Assembler

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

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

Кто знает Ассемблер помогите очень прошу. №2 Задано текст, слова в котором разделены пробелами и знаками препинания. Разработать программу, которая находит и выводит самую длинную цепочку из слов одинаковой длины. Если цепочек нет, то выводит сообщение об этом.(Цепочка - это последовательность из двух и более слов, находящихся рядом.)

Решение задачи: «Найти и вывести самую длинную цепочку из слов одинаковой длины»

textual
Листинг программы
LOCALS
 
.model small
 
.stack 100h
 
.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-1
        ;символы разделители слов
        DelimChars              db      '.,!?;:"() ', "'"
        LenDelimChars           dw      $-DelimChars
        ;переменные
        CrLf                    db      0Dh, 0Ah, '$'   ;перевод троки
        CurrChain               dw      ?       ;текущая длина цепочки
        CurrWordsLen            dw      ?       ;длина слова в текущей цепочке
        StartChain              dw      ?       ;адрес начала цепочки
        FinishChain             dw      ?
        MaxChain                dw      ?       ;максимальная длина цепочки
        MaxWordsLen             dw      ?       ;длина слова в максимальной цепочке
        MaxStartChain           dw      ?       ;адрес начала цепочки
        MaxFinishChain          dw      ?
        msgNoChain              db      'No chain', '$'
.code
 
main    proc
        mov     ax,     @data
        mov     ds,     ax
 
 
        mov     ax,     0
        mov     CurrChain,      ax
        mov     CurrWordsLen,   ax
        mov     StartChain,     ax
        mov     FinishChain,    ax
        mov     MaxChain,       ax
        mov     MaxWordsLen,    ax
        mov     MaxStartChain,  ax
        mov     MaxFinishChain, ax
 
        lea     si,     String
        mov     cx,     Len
 
        ;пропускаем все разделители
@@WhileDelimiter:
        mov     al,     [si]
        call    IsDelimChar
        cmp     ah,     0
        je      @@NewWord
        inc     si
        loop    @@WhileDelimiter
 
        jcxz    @@NewChain      ;если строка закончилась - выйти, но перед этим оценить
                                ;текущую цепочку
        ;найдено новое слово
@@NewWord:
        mov     dx,     0       ;длина очередного слова пока равна 0
        mov     di,     si      ;сохраняем адрес начала слова
        ;пропускаем все буквы слова до разделителя
@@WhileWord:
        mov     al,     [si]
        call    IsDelimChar
        cmp     ah,     0
        jne     @@Break
@@NextChar:
        inc     dx              ;увеличиваем длину слова
        inc     si              ;переходим к следующему символу
        loop    @@WhileWord
@@Break:
        ;сравниваем длину текущего слова с длиной слова в текущей цепочке
        cmp     dx,     CurrWordsLen
        jne     @@NewChain      ;если они не равны, то цепочка прервалась
@@ContChain:
        ;если цепочка продолжается, то увеличить длину цепочки
        inc     CurrChain
        mov     FinishChain,    si
        dec     FinishChain
        jmp     @@Next
@@NewChain:                     ;иначе - цепочка прервалась
        ;инициализация параметров новой цепочки
        mov     CurrChain,      1
        mov     CurrWordsLen,   dx
        mov     StartChain,     di
        mov     FinishChain,    si
        dec     FinishChain
        jmp     @@Next
 
@@Next:
        mov     ax,     CurrChain       ;сравниваем длину цепочки с максимальной
        cmp     ax,     MaxChain
        jbe     @@SkipCopy
        ;копирование параметров максимальной цепочки
        mov     ax,     CurrChain
        mov     MaxChain,       ax
        mov     ax,     CurrWordsLen
        mov     MaxWordsLen,    ax
        mov     ax,     StartChain
        mov     MaxStartChain,  ax
        mov     ax,     FinishChain
        mov     MaxFinishChain, ax
@@SkipCopy:
 
        jcxz    @@Finish
        jmp     @@WhileDelimiter
 
@@Finish:
 
        ;вывод результатов
        cmp     MaxChain,       2
        jae     @@ShowChain
        mov     ah,     09h
        lea     dx,     msgNoChain
        int     21h
        jmp     @@Exit
@@ShowChain:
        mov     si,     MaxStartChain
        mov     cx,     MaxFinishChain
        sub     cx,     si
        add     cx,     1
        call    ShowSubStr
 
@@Exit:
        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
 
;процедура вывода подстроки
;на входе:
;  ds:si - адрес первого символа подстроки
;  cx    - длина выводимой подсторки
ShowSubStr      proc
        push    ax
        push    bx
        push    cx
        push    dx
        mov     ah,     40h
        mov     bx,     1
        mov     cx,     cx
        mov     dx,     si
        int     21h
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
ShowSubStr      endp
 
end     main

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

  1. Объявление переменных в сегменте данных:
    • String - строка для исследования
    • Len - длина строки String
    • DelimChars - символы разделители слов
    • LenDelimChars - длина строки DelimChars
    • CrLf - символ перевода строки
    • CurrChain - текущая длина цепочки
    • CurrWordsLen - длина слова в текущей цепочке
    • StartChain - адрес начала цепочки
    • FinishChain - адрес конца цепочки
    • MaxChain - максимальная длина цепочки
    • MaxWordsLen - длина слова в максимальной цепочке
    • MaxStartChain - адрес начала максимальной цепочки
    • MaxFinishChain - адрес конца максимальной цепочки
    • msgNoChain - сообщение No chain
  2. Инициализация переменных:
    • Используются команды mov для установки начальных значений всех переменных в 0 - ax, CurrChain, CurrWordsLen, StartChain, FinishChain, MaxChain, MaxWordsLen, MaxStartChain, MaxFinishChain
  3. Чтение строки и анализ слов:
    • Используется цикл для чтения каждого символа в строке и анализа слов
    • При обнаружении нового слова устанавливается длина и проверяется соответствие длины предыдущего слова текущей цепочке
  4. Оценка цепочек:
    • Сравнение длины текущей цепочки со значениями максимальной длины цепочки, затем копирование параметров максимальной цепочки (если нужно)
  5. Вывод результатов:
    • Печать сообщения No chain в случае отсутствия цепочек заданной длины или вывод максимальной цепочки при её наличии
    • Используются команды mov, lea и int для вывода сообщений с использованием прерываний DOS
  6. Процедура IsDelimChar:
    • Определение, принадлежит ли символ к разделителям слов
  7. Процедура ShowSubStr:
    • Вывод подстроки на экран с использованием прерываний DOS
  8. Завершение программы:
    • Программа завершается с использованием прерывания DOS Этот код, возможно, написан на языке ассемблера для MS-DOS, так как используются прямые обращения к прерываниям DOS и регистрам процессора (например, ax, dx, ah).

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

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