В каждом слове определить количество повторений его первой буквы - Assembler/MASM

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

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

Добрый день дорогие программисты. С праздничком вас. Нужна помощь, есть слова разделенные пробелом и нужно определить количество повторений первой буквы в слове. И извиняюсь за попрошайничество.
; Template for console application 
.586 
.MODEL flat, stdcall 
OPTION CASEMAP:NONE 
Include kernel32.inc 
Include masm32.inc 
IncludeLib kernel32.lib 
IncludeLib masm32.lib 
.CONST 
MsgExit DB 13,10,"Press Enter to Exit",0AH,0DH,0
MsgInput DB "Please Input String",0AH,0DH,0
Symbol   db   's'
yes DB "YES"
no DB "NOO"
.DATA 
.DATA?
String DB 100 DUP (?)
Buf DB 2 DUP (?)
Result DB 22 DUP (' ')
.CODE 
Start:
XOR EAX,EAX
 
Input:
Invoke StdOut,ADDR MsgInput
Invoke StdIn,ADDR String,LengthOf String
 
cld
lea EDI,String
mov ECX,10
mov  al,Symbol
repne scasb
je equal
mov ecx,3
lea esi,no
lea edi,Result
rep movsb
jmp kon
equal:
mov ecx,3
lea esi,yes
lea edi,Result
rep movsb
kon:
XOR EAX,EAX
Invoke StdOut,ADDR Result
Invoke StdOut,ADDR MsgExit 
Invoke StdIn,ADDR Buf,LengthOf Buf 
Invoke ExitProcess,0 
End Start
Пока я сделал поиск определенной буквы и вывод есть ли он в строке.

Решение задачи: «В каждом слове определить количество повторений его первой буквы»

textual
Листинг программы
.486
.model flat, stdcall
option casemap :none
 
        include \masm32\include\windows.inc
 
        include \masm32\include\user32.inc
        include \masm32\include\kernel32.inc
        include \masm32\include\masm32.inc
 
        includelib \masm32\lib\user32.lib
        includelib \masm32\lib\kernel32.lib
        includelib \masm32\lib\masm32.lib
.data
        DelimChar       equ     ' '
        aszCrLf         db      0Dh, 0Ah, 0
        aszPrompt       db      'Введите строку:', 0Dh, 0Ah, 0
        aszMsgResult    db      '%d-ое слово %d повторений', 0Dh, 0Ah, 0
        aszPressLeftAlt db      0Dh, 0Ah, 0Dh, 0Ah, "Press Left Alt to exit", 0
.data?
        hConsoleOutput  HANDLE  ?
        hConsoleInput   HANDLE  ?
        WordsCount      dd      ?
        BufLen          dd      ?
        Buffer          db      1024 dup(?)
        StringLen       dd      ?
        String          db      1024 dup(?)
.code
 
start   proc
 
        ; получение описателей ввода и вывода консоли
        invoke  GetStdHandle,   STD_INPUT_HANDLE
        mov     hConsoleInput,  eax
        invoke  GetStdHandle,   STD_OUTPUT_HANDLE
        mov     hConsoleOutput, eax
        ;очистка экрана
        invoke  ClearScreen
        ;преобразование кодировки символов кириллицы
        invoke  CharToOem,      ADDR aszPrompt, ADDR aszPrompt
        invoke  CharToOem,      ADDR aszMsgResult, ADDR aszMsgResult
        ;ввод исходных данных - строки
        invoke  WriteConsole, hConsoleOutput, ADDR aszPrompt,\
                LENGTHOF aszPrompt - 1, ADDR BufLen, NULL
        invoke  ReadConsole, hConsoleInput, ADDR String,\
                LENGTHOF String, ADDR StringLen, NULL
        lea     esi,    [String]        ;удаление из буфера
        add     esi,    [StringLen]     ;символов перевода строки
        mov     [esi-2],word ptr 0
        sub     [StringLen],    2
 
        lea     esi,    [String]
        mov     ecx,    [StringLen]
        mov     [WordsCount],   0
        jecxz   @@Finish
        ;пропускаем все разделители
@@WhileDelimiter:
        mov     al,     [esi]
        cmp     al,     DelimChar
        jne     @@NewWord
        inc     esi
        loop    @@WhileDelimiter
 
        jecxz   @@Finish        ;если строка закончилась - выйти
        ;найдено новое слово
@@NewWord:
        mov     ah,     al      ;запомним 1-й символ слова
        mov     ebx,    0       ;количество 1-х символов в слове
        inc     [WordsCount]    ;увеличиваем счётчик слов на 1
        ;пропускаем все буквы слова до разделителя
@@WhileWord:
        mov     al,     [esi]
        cmp     al,     DelimChar
        je      @@Break
        cmp     al,     ah
        jne     @@NoInc
        inc     ebx
@@NoInc:
        inc     esi             ;переходим к следующему символу
        loop    @@WhileWord
@@Break:
        ;вывод результатов
        pushad
        invoke  wsprintf, ADDR Buffer, ADDR aszMsgResult, [WordsCount], ebx
        invoke  StrLen, ADDR Buffer
        mov     [BufLen],       eax
        invoke  WriteConsole, hConsoleOutput, ADDR Buffer,\
                BufLen, ADDR BufLen, NULL
        popad
 
        jecxz   @@Finish
        jmp     @@WhileDelimiter
@@Finish:
 
        ;ожидание нажатия Left Alt
        invoke  WriteConsole, hConsoleOutput, ADDR aszPressLeftAlt,\
                LENGTHOF aszPressLeftAlt - 1, ADDR BufLen, NULL
        @@WaitForLAlt:
                invoke  GetAsyncKeyState, VK_LMENU
                and     eax,    8000h
        jz      @@WaitForLAlt
        ;завершение программы
        invoke  ExitProcess, 0
start   endp
 
end start

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

Этот код на языке ассемблера предназначен для подсчета количества повторений первой буквы каждого слова в строке, введенной пользователем. Список переменных и их значений:

  1. .486 - версия операционной системы Windows.
  2. .model flat, stdcall - модель сегментации данных и сегментации кода, а также метод вызова процедур.
  3. option casemap :none - опция, отменяющая преобразование регистра символов.
  4. include \masm32\include\windows.inc - включает в себя необходимые определения и константы Windows API.
  5. include \masm32\include\user32.inc - включает в себя определения и константы API User32.
  6. include \masm32\include\kernel32.inc - включает в себя определения и константы API Kernel32.
  7. include \masm32\include\masm32.inc - включает в себя определения и константы MASM32.
  8. aszCrLf db 0Dh, 0Ah, 0 - строка, представляющая символ новой строки (0Dh) и символ возврата каретки (0Ah).
  9. aszPrompt db 'Введите строку:', 0Dh, 0Ah, 0 - строка, которая будет выводиться пользователю для ввода строки.
  10. aszMsgResult db '%d-ое слово %d повторений', 0Dh, 0Ah, 0 - строка, которая будет выводиться пользователю с результатом подсчета.
  11. aszPressLeftAlt db 0Dh, 0Ah, 0Dh, 0Ah, 'Press Left Alt to exit', 0 - строка, которая будет выводиться пользователю для подтверждения выхода.
  12. hConsoleOutput HANDLE ? - дескриптор вывода консоли.
  13. hConsoleInput HANDLE ? - дескриптор ввода консоли.
  14. WordsCount dd ? - счетчик количества слов в строке.
  15. BufLen dd ? - счетчик длины строки.
  16. Buffer db 1024 dup(?) - буфер для ввода и вывода данных.
  17. StringLen dd ? - счетчик длины строки в буфере.
  18. String db 1024 dup(?) - буфер для хранения строки, введенной пользователем. Список действий:
  19. Получение дескрипторов ввода и вывода консоли с помощью функции GetStdHandle.
  20. Очистка экрана с помощью функции ClearScreen.
  21. Преобразование кодировки символов кириллицы с помощью функции CharToOem.
  22. Ввод строки с помощью функции ReadConsole.
  23. Удаление символов перевода строки из буфера с помощью цикла и операции sub.
  24. Проверка каждого символа введенной строке на соответствие разделителю слова (пробелу) с помощью цикла и операции cmp.
  25. Если символ является разделителем, переходим к следующему слову.
  26. Если символ является первым символом слова, сохраняем его в отдельной переменной и устанавливаем счетчик повторений в 1.
  27. Если символ не является первым символом слова, увеличиваем счетчик повторений на 1.
  28. После подсчета всех слов, выводим результат на экран с помощью функции WriteConsole и функции wsprintf, которая форматирует строку с количеством повторений и именем слова.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

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

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