Страница 1 из 1

Как поменять слова в строке местами?

Добавлено: 14 дек 2009, 17:56
z-z-z-sleep
Задача звучит так:
Введенном с помощью клавиатуры предложении поменять местами слова с максимальной и минимальной длинами. Результат отразить в верхней части экрана.
Помогите пожалуйста!

Re: Как поменять слова в строке местами?

Добавлено: 14 дек 2009, 21:40
airyashov
выкладывайте наработки

Re: Как поменять слова в строке местами?

Добавлено: 15 дек 2009, 13:19
z-z-z-sleep
airyashov писал(а):выкладывайте наработки
есть похожая программа, но доработать ее не могу (

.386

dseg segment use16

strn db 0050h dup (0) ; Введённая строка

dseg ends

cseg segment use16

assume cs:cseg, ds:dseg, ss:sseg

@: mov ax, dseg

mov ds, ax

mov es, ax

; Вводим строку

mov ah, 3Fh

mov cx, 0050h

xor dx, dx

xor bx, bx

int 21h

; Удаляем CRLF

mov di, ax

sub di, 2

; Заодно находим длину строки

; В CX будет храниться количество необработанных символов

mov cx, di

mov word ptr [di], 0

; Устанавливаем DI на последний символ

dec di

; В AL заносим разделитель

mov al, 20h

; Пропускаем концевые пробелы

std

repe scasb

inc di ; "Занесло"

mov bp, di ; Сохраним адрес последнего символа слова

inc cx ; CX тоже

; Найдём начало

repne scasb

; Если не нашли пробел перед словом, то слово простирается до начала строки => строка из одного слова

jne short @quit

; Иначе в SI сохраняем адрес начала последнего слова

lea si, [di+2]

; В BP высчитываем его длину

sub bp, si

inc bp

; Далее пойдём от начала строки

xor di, di

; Запоздавшая корректировка CX

inc cx

cld

; Цикл, находящий слова и выводящий подходящие

; Разделитель в AL

@1: mov al, 20h

; Пропускаем пробелы в начале строки и между словами

repe scasb

; Если необработанных непробельных символов больше нет, то закругляемся

je short @quit

; Иначе корректируемся на первый непробельный символ

inc cx

dec di

; В DX сохраним адрес начала слова

mov bx, di

mov dx, di

; Найдём его конец

repne scasb

; DI вернём на пробел после слова

dec di

inc cx

; Найдём длину слова в BX

sub bx, di

neg bx

; Сравним его длину с длиной последнего слова

cmp bx, bp

jne short @2

; Если длины совпали, то сами слова могут совпасть

push si

push di

push cx

; В CX длина слов

mov cx, bp

; В DI - начало тестируемого слова

mov di, dx

; В SI - начало последнего слова

; Сравниваем

repe cmpsb

pop cx

pop di

pop si

; Если равны, то выводить не надо

je short @1

; Проверим второе условие

@2: push di

push si

push cx

; Возьмём первую букву

mov si, dx

lodsb

; И поищем её в остатке слова

mov di, si

mov cx, bx

dec cx

repne scasb

pop cx

pop si

pop di

; Если не нашли, переходим к следующему слову

jne short @1

; Иначе выводим

push cx

; Выведем символы слова

mov cx, bx

; И ещё один - символ после слова - пробел, чтобы разделить выводимые слова

inc cx

xor bx, bx

mov ah, 40h

; В DX уже хранится адрес начала слова

int 21h

pop cx

jmp short @1

; Перед выходом переведём строку

@quit: mov ah, 02h

mov dl, 0Dh

int 21h

mov dl, 0Ah

int 21h

mov ax, 4C00h

int 21h

cseg ends

sseg segment stack use16

db 0400h dup (?)

sseg ends

end @