daily pastebin goal
45%
SHARE
TWEET

Untitled

a guest Mar 26th, 2019 54 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;/****************************************************************************/;
  2. ;;  Задание:
  3. ;; Програма вводит строку текста и выводит множество символов этой строки в
  4. ;; порядке убывания числа вхождений каждого символа в строку.
  5. ;; Выходное множество символов представляется в формате ""C1:N1,C2:N2,...",
  6. ;; где Ci - символ, а Ni - число вхождений этого символа, представленное в
  7. ;; десятичном виде. Если какие-либо слова строки могут быть интерпретированы
  8. ;; как беззнаковые пятиричные числа (размерность не более 2 байт), то цифры этих
  9. ;; чисел не попадают в процесс формирования выходного множества. Сумма всех
  10. ;; таких чисел выводится в двоичном виде.
  11. ;/****************************************************************************/;
  12. ;сегмент данных
  13. datas segment
  14.     maxlength_in db 79         ;начало буфера для входной строки
  15.     length_in db 0             ;реально введеннное количество символов
  16.     string_in db 80 dup('0')  
  17.  
  18.     length db 0                 ;длина строки, не содержащей пятиричных чисел
  19.     string db 79 dup ('0')     ;сама строка
  20.  
  21.     length2 db 0                ;длина массива символов  
  22.     symbols db 158 dup ('$')    ;массив символов в виде [ASCII код символа][частота]  
  23.    
  24.     sum dw 0                    ;сумма всех пятиричных чисел
  25.     max_frequency db 0          ;максимальная частота    
  26.     digitFh db 05h              
  27.     fiveexp dw 1                ;Табличка для перевода из основания 5
  28.                 dw 5    ;в основание 10
  29.                 dw 25
  30.                 dw 125
  31.                 dw 625
  32.                     dw 3125
  33.                     dw 15625                  
  34.     numFlag db 0
  35.     wordLength db 0
  36.     numberLength db 0    
  37.  
  38.     message01 db 10,13,'Введите строку:',10,13,'->$'  
  39.     message02 db 0,' : ',30h,30h,30h,10,13,'$'
  40.     message03 db 10,13,'Вхождение символов:',10,13,'$'
  41. datas ends
  42.  
  43. ;сегмент стека
  44. stacks segment
  45.     db 100h dup(?)
  46. stacks ends
  47.  
  48. ;сегмент кода
  49. codes segment
  50.     assume ss:stacks, ds:datas, cs:codes
  51.  
  52. ;/****************************************************************************/;
  53. ; Ввод строки и определение ее длины
  54. ;/****************************************************************************/;
  55. enter_string proc          
  56.     mov ah,0Ah                    
  57.     lea dx,maxlength_in
  58.     int 21h
  59.     ret
  60. enter_string endp
  61.  
  62. ;/****************************************************************************/;
  63. ; подсчет частоты каждого символа
  64. ;/****************************************************************************/;
  65. calculate_symbols proc
  66.     LOCALS
  67.     cmp length,0            ;Длина стороки без чисел = 0   
  68.     jz @@end               
  69.  
  70.     xor bx,bx
  71.     mov bl,length           ;bх = length
  72.     xor di,di               ;di для строки symbols
  73.     mov si,-1
  74.     mov dl,20h              ;в dl код пробела
  75.     mov dh,0
  76. @@scan_beg:                            
  77.     inc si              ;идем по циклу в поисках нового символа
  78.     cmp si,bx               ;Надеюсь ещё не конец строки
  79.     jge @@scan_end          ;А ТО КАК....
  80.     mov al,string[si]           ;al = string[si]
  81.     cmp al,dl               ;al = пробел?
  82.     jz @@scan_beg                       ;Если ,то следю символ, а так -  дальше
  83.  
  84.     push si             ;подсчет кол-ва символов
  85.     mov ah,1                ;Ага, первое вхождение уже есть!!!
  86. @@calc_freq_beg:
  87.     inc si                       
  88.     cmp si,bx
  89.     jge @@calc_freq_end         ;Искать до конца строки!!!
  90.     cmp string[si],al           ;Неужли снова он?
  91.     jne @@calc_freq_beg         ;Не, показалось!!!
  92.     inc ah                              ; Или всё-таки ОН?!?!
  93.     mov string[si],dl   ;заменяем новый, подсчитанный символ на пробел
  94.     jmp short @@calc_freq_beg           ;Что бы не видеть его снова, походу!!!
  95.                     ;Или нам так больше нравится?!?!
  96. @@calc_freq_end:
  97.     cmp ah,max_frequency   ;определяем максимальную частоту среди символов
  98.     jle @@not_greater
  99.     mov max_frequency,ah                ;и заносим её из ah
  100. @@not_greater:
  101.     mov word ptr symbols[di],ax     ;записываем в массив symbols код символа
  102.                     ;и его частоту
  103.     add di,2                ;в di 2,т.к. у нас там и символ и его вхождение
  104.     pop si              ;Так или иначе, а начнём мы все равно
  105.                     ;с символа, следующего за предыдущим!!!
  106.    
  107.     jmp short @@scan_beg
  108. @@scan_end:
  109.  
  110.     mov dx,di                       ;длина массива symbols
  111.     mov length2,dl
  112. @@end:    
  113.     ret
  114. calculate_symbols endp
  115.  
  116.  
  117. ;/****************************************************************************/;
  118. ; вывод "символ : частота "
  119. ;/****************************************************************************/;
  120. print_symbols proc
  121.     LOCALS
  122.     cmp length,0        ;В строке с символами кто нибудь наблюдается???
  123.     jz @@for1end                ;@@for1end - зашифрованная метка конца процедуры!
  124.  
  125.     xor di,di
  126.     mov bx,0A64h        ;в bh - 10, в bl - 100
  127.     xor cx,cx
  128.     mov cl,length2      ;В сх длину строки symbols
  129.    
  130. @@for1beg:
  131.     cmp max_frequency,0h    ;Если получилось так, что символов с нулевым
  132.                 ;вхождением отсутствует, тогда          
  133.     jz @@for1end        ;конец!!!
  134.  
  135.     xor si,si                   ;Счётчик, с помощью колторого просматриваем строку.
  136. @@for2beg:
  137.     cmp si,cx           ;Ба, конец!!! Надо уменьшить max_frequency
  138.     jge @@for2end
  139.     mov ax,word ptr symbols[si] ;ах = очередному символу.
  140.     cmp ah,max_frequency    ;частота символа меньше максимальной - не выводим
  141.     jnz @@not_equal_max
  142.                                 ;ZYRAB
  143.     mov message02[0],al           ;вывод символа symbols[si]
  144.     inc si    
  145.                
  146.     mov al,ah                     ;делим на 100 - выделяем цифру сотен
  147.     xor ah,ah
  148.     div bl
  149.     add message02[4],al
  150.  
  151.     mov al,ah                     ;делим на 10 - выделяем цифры десятков и единиц
  152.     xor ah,ah
  153.     div bh
  154.     add message02[5],al
  155.     add message02[6],ah
  156.  
  157.     mov ah,09h
  158.     lea dx,message02
  159.     int 21h
  160.  
  161.     mov message02[4],30h
  162.     mov message02[5],30h
  163.     mov message02[6],30h    ;начиная от ZYRAB, сначала выводится символ
  164.                 ;а затем, количество вхождений.
  165.  
  166.     inc si                      
  167.     jmp short @@for2beg
  168. @@not_equal_max:
  169.     add si,2    
  170.     jmp short @@for2beg
  171. @@for2end:          ;А здесь как раз и творится беспредел с
  172.     dec max_frequency       ;уменьшением числа вхождений
  173.     jmp @@for1beg       ;Будем искать символ с меньшим вхождением!!!Go!!!
  174. @@for1end:
  175.  
  176.     ret
  177. print_symbols endp
  178.  
  179.  
  180. ;/****************************************************************************/;
  181. ; поиск пятиричных чисел и вывод их суммы
  182. ;/****************************************************************************/;
  183. find_pental_numbers proc
  184.     LOCALS
  185.     cmp length_in,0     ;Вы забыли ввести символы???
  186.     jnz @@ok
  187.     jmp @@binary_sum_end   
  188. @@ok:
  189.     mov si,-1           ;si счётчик.
  190.     xor di,di           ;Очень важный момент!!!
  191.     xor bh,bh           ;в bx - length_in
  192.     mov bl,length_in
  193.  
  194. @@calc_sum_beg:
  195.     inc si         
  196.     cmp si,bx           ;если не конец строки
  197.     jl @@ok1            ;то дальше
  198.     jmp @@calc_sum_end      ;Единственный выход из этой процедуры
  199. @@ok1:
  200.     cmp string_in[si],20h   ;если пробел - переходим к следующему символу
  201.     jz @@calc_sum_beg
  202.  
  203.                 ;ПОДСЧЁТ ДЛИНЫ ОЧЕРЕДНОГО СЛОВА
  204.     push si         ;si в стек
  205.     mov wordLength,1        ;В wordLength длина слова
  206.     inc si
  207. @@calc_length_beg:              
  208.     cmp si,bx                   ;если конец строки,
  209.     jge @@calc_length_end      
  210.     cmp string_in[si],20h   ;ИЛИ ПРОБЕЛ
  211.     jz @@calc_length_end    ;то закончим с определением wordLength
  212.     inc wordLength
  213.     inc si
  214.     jmp short @@calc_length_beg
  215. @@calc_length_end:
  216.     pop si          ;si из стека
  217.                  
  218.     cmp wordLength,7        ;максимальное пятиричное число - 4044120(5)=65535(10)
  219.     jg @@copy_word_beg
  220.  
  221.     push si         ;ПРОВЕРКА НА 5тиричные цифры
  222.     mov cl,wordLength           ;В cl длину слова
  223.     mov numberLength,0      ;Длина числа = 0
  224.  @@check_word_beg:
  225.     xor ax,ax
  226.     cmp si,bx
  227.     jge @@check_word_end        ;Лишь бы не конец строки
  228.     cmp string_in[si],30h           ;Если <'0'
  229.     jl @@check_word_end
  230.     cmp string_in[si],34h           ;или >'4'
  231.     jg @@check_word_end             ;то это не число!!!
  232.     inc numberLength   
  233.     inc si
  234.     inc ax                          ;Это логика!!! (true or false)
  235.     dec cl
  236.     cmp cl,0
  237.     jg @@check_word_beg
  238. @@check_word_end:
  239.     pop si
  240.    
  241.     cmp ax,0            ;Прочитанное слово не число!!!
  242.     jz @@copy_word_beg
  243.    
  244.     xor dh,dh           ;преобразование в число
  245.     mov dl,numberLength             ;В dx - количество цифр в числе
  246.     push dx            
  247.     xor cx,cx                      
  248.     push si
  249.     push di
  250.     xor di,di
  251.     add  si,dx          ;si указывает на конец числа.
  252.     dec si
  253. @@convert_beg:
  254.     xor ax,ax
  255.     mov al, byte ptr string_in[si]  ;Преобразование с конца
  256.     sub al,30h     
  257.     mul fiveexp[di]         ;Помните табличку для перевода из
  258.                     ;основания 5 в основание 10
  259.     add cx,ax                       ;В сх - десятичное представление числа
  260.     add di,2
  261.     dec si                          ;Мы ещё ближе к началу числа
  262.     dec numberLength
  263.     cmp numberLength,0              ;От числа ещё что-то осталось
  264.     jg @@convert_beg
  265. @@convert_end:             
  266.     pop di
  267.     pop si
  268.     pop dx
  269.     add si,dx
  270.     add sum,cx          ;Скаладываем с тем что есть
  271.     jmp @@calc_sum_beg
  272.  
  273. @@copy_word_beg:                       ;копируем слово в строку символов
  274.     cmp wordLength,0                  
  275.     jnz @@ok2
  276.     jmp @@calc_sum_beg          ;Перепрыгнуть туда, где определ-ся
  277.                     ;Длина слова, числа и т.п.
  278. @@ok2:    
  279.     mov al,string_in[si]               ;В аl - очередной символ
  280.     mov string[di],al                  ;Засунем мы его в строку без чисел!!!
  281.     inc di
  282.     inc si
  283.     dec wordLength
  284.     jmp short @@copy_word_beg    
  285.  
  286. @@calc_sum_end:
  287.     mov bx,di
  288.     mov length,bl           ;В байте bl - длина строки без чисел
  289.                     ;Помещаем это чило в length
  290.  
  291.     mov bx,sum              ;Почти стандартный вывод суммы
  292.     mov cx,16               ;в двоичном виде даже ничего интересного нет!!!
  293.     mov ah,2h
  294. @@binary_sum_end:  
  295.     ret
  296. find_pental_numbers endp
  297.  
  298.  
  299. ;/****************************************************************************/;
  300. ; точка входа
  301. ;/****************************************************************************/;
  302. main:
  303.     mov ax,datas
  304.     mov ds,ax
  305.  
  306.     mov ah,9h                    ;вывод приглашения
  307.     lea dx,message01
  308.     int 21h
  309.  
  310.     call enter_string            ;ввод строки
  311.  
  312.     call find_pental_numbers      ;поиск пятиричных чисел и вывод их суммы
  313.  
  314.     mov ah,9h
  315.     lea dx,message03
  316.     int 21h
  317.  
  318.     call calculate_symbols       ;подсчет частоты символов
  319.     call print_symbols           ;вывод данных
  320.  
  321.     mov ah,4Ch
  322.     int 21h
  323. codes ends
  324.     end main
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top