Консультация # 189157: Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: Мне надо бы сделать "СОРТИРОВКУ СЛОВ ПО ТРЕТЕЙ БУКВЕ". Помогите пожалуйста. очень надоо. ...
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: Мне надо бы сделать "СОРТИРОВКУ СЛОВ ПО ТРЕТЕЙ БУКВЕ". Помогите пожалуйста. очень надоо.
.model small
.code ;сегмент кода
.startup ;инициализация сегментов для выбранной модели памяти
call GetString ;вводим строку
call ParseString ;разбираем строку на слова
call SortWords ;сортируем слова
call OutSortWords ;выводим слова
mov ah, 0 ;ждем нажатие на клавишу
int 16h
.exit 0
GetString proc ;вводим строку
lea dx, sEnterString
mov ah, 9 ;выведем строку приглашения
int 21h
lea dx, max ;вводим строку
mov ah, 0ah
int 21h
ret
GetString endp
isLetter proc ;проверка на букву
cmp al, 'A' ;буквы - только английские
jb not_letter
cmp al, 'Z'
jbe yes_letter
cmp al, 'a'
jb not_letter
cmp al, 'z'
jbe yes_letter
not_letter:
stc ;не буква
ret
yes_letter:
clc ;буква
ret
isLetter endp
ParseString proc ;разбор строки на слова
xor cx, cx ;счетчик слов
lea si, String ;адрес введенной строки
lea bx, array ;адрес массива, где будем сохранять
; начало каждого слова и длину слова
xor di, di ;счетчик букв в слове
Parse_loop: ;цикл разбора
lodsb ;очередной символ
cmp al, 0dh ;символ конца строки (после ф-и 0ah)
je Parse_last ;на анализ последнего слова
call isLetter ;проверяем на букву
jc Parse_word_found;разделитель?
test di, di ;первая буква?
jnz Parse_next_letter ;нет - на счет букв
lea dx, [si-1] ;для первой запоминаем начало слова
Parse_next_letter:
inc di ;считаем буквы
jmp Parse_loop ;на повтор
Parse_word_found: ;разделитель
test di, di
je Parse_loop ;букв не было - игнорируем разделители
mov [bx], dx ;есть слово - сохраняем начало слова
mov [bx+2], di ; и длину
add bx, 4 ;на следующий элемент массива
xor di, di ;обнуляем счетчик букв
inc cx ;считаем слова
jmp Parse_loop ;на повтор
Parse_last: ;конец строки
test di, di ;было ли последнее слово
je Parse_ret
mov [bx], dx ;сохраняем начало
mov [bx+2], di ;длину
inc cx ;считаем
Parse_ret:
mov count, cx ;сохраним счетчик
ret
ParseString endp
;сравнение слов
;аргументы: si - индекс первого элемента массива
; di - второго
;слова длиной меньшей 3 считаем минимальными, считаем символ нулем
CompWords proc
mov bx, si ;первый
cmp word ptr array[bx+2], 3 ;длина меньше 3?
jge long_word_1 ;>= - считываем третий символ
mov al, 0 ;иначе = 0
jmp from_word_2 ;символ второго слова
long_word_1:
mov bx, array[bx] ;адрес начала слова
mov al, [bx+2] ;третий символ
from_word_2:
mov bx, di ;второй
cmp word ptr array[bx+2], 3
jge long_word_2
mov ah, 0
jmp cmp_letters
long_word_2:
mov bx, array[bx]
mov ah, [bx+2]
cmp_letters: ;сравнение символов
cmp al, ah
jl set_less
jz set_equal
set_great:
mov ax, 1 ;признак >
ret
set_less:
mov ax, -1 ;признак <
ret
set_equal: ;признак =
xor ax, ax
ret
CompWords endp
SortWords proc ;сортировка "пузырьком"
mov cx, count ;считаем, только если слов > 2
cmp cx, 2
jb SortWords_ret
;зададим правую границу цикла 2
shl cx, 1
shl cx, 1
mov dx, cx
sub dx, 4 ;правая граница цикла 1
xor si, si ;индекс цикла 1
SortWords_loop1: ;цикл 1
lea di, [si+4] ;индекс цикла 2, di = si+1
; (+4, т.к элемент массива имеет размер 4 байта)
SortWords_loop2: ;цикл 2
call CompWords ;сравниваем элементы si и di
test ax, ax ;проверяем результат
jle SortWords_next2 ;<= ничего не делаем
mov ax, array[si] ;меняем местами адрес слова
xchg array[di], ax
mov array[si], ax
mov ax, array[si+2] ;и длину
xchg array[di+2], ax
mov array[si+2], ax
SortWords_next2:
lea di, [di+4] ;на следующий элемент цикла 2
cmp di, cx ;дошли до конца?
jb SortWords_loop2
lea si, [si+4] ;на следующий элемент цикла 1
cmp si, dx ;дошли до конца?
jb SortWords_loop1
SortWords_ret:
ret
SortWords endp
OutSortWords proc ;вывод отсортированных слов
lea dx, sResult ;строка "Sorted words: "
mov ah, 9
int 21h
mov di, count ;количество слов
xor bx, bx ;индекс в массиве элементов массива
mov ah, 2 ;ф-я вывода символа dl на экран
PrintWords_loop:
mov si, array[bx] ;адрес слова
mov cx, array[bx+2] ;длина
PrintWord_loop:
mov dl, [si]
inc si
int 21h
loop PrintWord_loop ;выводим в цикле
mov dl, ' ' ;отделим пробелом
int 21h
add bx, 4 ;на следующий элемент (слово)
dec di ;все слова?
jne PrintWords_loop
mov dl, 0dh
int 21h
mov dl, 0ah ;перевод строки
int 21h
ret
OutSortWords endp
.data
sEnterString db "Enter string: $" ;приглашение ввести строку
sResult db 0dh,0ah,"Sorted words: $"
;буфер для ввода строки-вещественного числа
max db 128 ;размер буфера
len db ? ;реальная длина
String db 128 dup (?) ;сама строка
even ;выровняем адрес памяти на слово
count dw ? ;количество слов
array dw 256 dup (?) ;массив элементов, в которых адрес слова и длина
end
Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 13.04.2016, 16:14
5
нет комментария ----- Дата оценки: 14.04.2016, 10:36
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались.
Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора -
для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение.
Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал,
который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом.
Заходите - у нас интересно!