Отсортировать слова в строке во возрастанию количества символов - Assembler
Формулировка задачи:
Дана строка, нужно отсортировать слова в строке во возрастанию количества символов и занести это в файл.
Изначальная строка находится в файле
Ниже мой код, но не пашет...., не могу понять ошибку
.model small .stack 100h .data CR = 0Dh LF = 0Ah FileName db "sentence.txt","$" FDescr dw ? NewFile db "newfile.txt","$" FDescrNew dw ? maxCount dw 0 char db 'a' Buffer dw ? String dw 40 dup(0) index dw 0 MessageError1 db CR, LF, "File was`t opened!", "$" MessageError2 db CR, LF, "Error reading the file!", "$" MessageError3 db CR, LF, "File was`t found!", "$" MessageError4 db CR, LF, "File was`t created!", "$" MessageError5 db CR, LF, "Error writing the file!", "$" MessageEnd db CR, LF, "Program was successfully finished!", "$" dop dw ? count dw '0' crlf db 13,10,'$' .code start: print_string macro mov ah, 09h int 21h endm mArrangeWordsInAscending macro source,target local exit,first,second,third,start push ax push bx push cx push dx start: xor bx,bx xor ax,ax xor cx,cx lea di,byte ptr source+2 inc count mov cl,byte ptr source+1 first: mov bx,di cld mov al,' ' repne scasb jne start push di push cx sub di,bx dec di xor ax,ax mov ax,di cmp count,ax je second pop cx pop di jmp first second: mov cx,di inc cx xor ax,ax mov al, byte ptr target+1 mov si,ax lea di, target+si mov si,bx add target+1,cl cld rep movsb pop cx pop di xor ax,ax mov al, byte ptr target+1 cmp byte ptr source+1,al jbe exit jmp first exit: pop dx pop cx pop bx pop ax endm write macro srt push ax push dx lea dx, str mov ah,09h int 21h pop dx pop ax endm putdigit macro local lput1 local lput2 local exx push ax push cx push -1 mov cx,10 lput1: xor dx,dx mov ah,0 div cl mov dl,ah push dx cmp al,0 jne lput1 mov ah,2h lput2: pop dx cmp dx,-1 je exx add dl,'0' int 21h jmp lput2 exx: mov dl,' ' int 21h pop cx pop ax endm mov ax,@data mov ds,ax mov ah,3Dh xor al,al mov dx,offset FileName xor cx,cx int 21h mov FDescr,ax jnc M1 jmp Er1 CloseFile macro FileDescr mov ah, 3eh ;закрытие файла mov bx, FileDescr int 21h endm M1: mov ah,3ch xor cx,cx mov dx,offset NewFile int 21h mov FDescrNew, ax ;дискриптор файла jnc M2 ;eсли ошибок нет, продолжить jmp Er3 ;ошибка,файл не был создан M2: mov ah,3fh mov bx,FDescr mov cx,1 mov dx,offset Buffer int 21h jnc M3 ;если ошибок нет,продолжить jmp Er2 ;файл не был прочтён M3: cmp ax,0 je M4 mov ax,Buffer mov bx,index mov String[bx],ax jmp M2 M4: mArrangeWordsInAscending String jnc M6 jmp Er4 Er1: ;файл не был найден cmp ax, 02h jne M5 lea dx, MessageError3 print_string jmp Exit M5: ;файл не был открыт lea dx, MessageError1 print_string jmp Exit Er2: ;файл не был прочтен lea dx, MessageError2 print_string jmp Exit Er3: ;файл не был создан lea dx, MessageError4 print_string jmp Exit Er4: ;ошибка при записи в файл lea dx, MessageError5 print_string jmp Exit M6: CloseFile FDescr ;функция закрытия файла CloseFile FDescrNew lea dx, MessageEnd print_string jmp Exit Exit: mov ah, 07h int 21h mov ax, 4c00h int 21h end start
Решение задачи: «Отсортировать слова в строке во возрастанию количества символов»
textual
Листинг программы
{.$define Debug} PROGRAM SortWords; TYPE TRecWordProperty = RECORD StartPos : Integer; WordLen : Integer; END; TArrWordProperty = array [1..128] of TRecWordProperty; PROCEDURE ProcessStr(VAR SStr, DStr : String); VAR m : TArrWordProperty; WordCount : Integer; i, j : Integer; MinLen : Integer; MinIndex : Integer; BEGIN WordCount:=0; {количество слов в строке} i:=1; {текущая позиция в анализируемой строке} while i<=Length(SStr) do begin {ищем первую букву слова} while (i<=Length(SStr)) do begin if (SStr[i] = ' ') then Inc(i) else Break; end; if i>Length(SStr) then Break; Inc(WordCount); m[WordCount].StartPos:=i; {теперь просматриваем слово пока не закончится строка или не начнутся ограничители слов} while (i<=Length(SStr)) do if (SStr[i] = ' ') then Break else Inc(i); m[WordCount].WordLen:=i-m[WordCount].StartPos; end; {$IFDEF Debug} for i:=1 to WordCount do WriteLn(i:2,'. "',copy(SStr, m[i].StartPos, m[i].WordLen),'"'); {$ENDIF} DStr:=''; for i:=1 to WordCount do begin MinLen:=m[i].WordLen; MinIndex:=i; for j:=i+1 to WordCount do begin if MinLen<m[j].WordLen then begin MinLen:=m[j].WordLen; MinIndex:=j; end; end; if i<>1 then DStr:=DStr+' '; with m[MinIndex] do DStr:=DStr+copy(SStr, StartPos, WordLen); {тут можно сделать обмен, но массив нам дальше не понадобится} if i<>MinIndex then begin m[MinIndex].WordLen :=m[i].WordLen; m[MinIndex].StartPos:=m[i].StartPos; end; end; END; VAR s, SNew : String; BEGIN WriteLn('Input string:'); {$IFDEF Debug} s:='один два три четыре пять шесть семь восемь девять a'; WriteLn(s); {$ELSE} ReadLn(s); {$ENDIF} ProcessStr(s, SNew); WriteLn(SNew); END.
Объяснение кода листинга программы
- В начале кода объявляются типы данных TRecWordProperty и TArrWordProperty.
- Далее, определяется процедура ProcessStr, которая принимает два параметра типа String: SStr и DStr.
- Внутри процедуры объявляются следующие переменные:
- WordCount: количество слов в строке;
- i, j: текущие позиции в анализируемой строке;
- MinLen, MinIndex: используются для хранения минимальной длины слова и его индекса;
- m: массив для хранения свойств каждого слова.
- Далее, в цикле происходит поиск слов в строке и заполнение массива m.
- Если определен флаг Debug, то выводится информация о каждом найденном слове.
- Затем, в цикле происходит сортировка слов в строке по возрастанию их длины.
- После сортировки, выводится отсортированная строка.
- В основной части программы, после объявления переменных s и SNew, происходит чтение строки из консоли и вызов функции ProcessStr.
- Результат сортировки выводится на экран.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д