Консультация № 189125
08.04.2016, 13:10
0.00 руб.
0 3 1
Уважаемые эксперты! Пожалуйста, ответьте на вопрос:
Доброго времени суток, уважаемые эксперты! Мне нужна ваша помощь!
Суть задания заключается в следующем:
реализовать программу со строками. Слова в строке могут быть разделены пробелами и знаками препинания. Удалить в каждом слове строки повторяющиеся в нем буквы.
Помогите, пожалуйста.
Буду очень благодарен за помощь. Добра и позитива!

Обсуждение

давно
Посетитель
7438
7205
08.04.2016, 16:29
общий
это ответ
Здравствуйте, Maxim!
Где-то так... Идея такая:
1) ищем слова, состоящие из латинских букв. Все остальное - разделители
2) обнуляем в каждом слове одинаковые буквы
3) сжимаем строку, удаляя из нее нули
Комментариев более чем достаточно. Смотрите. С вопросами - в мини-форум
[code lang=asm h=200]
;реализовать программу со строками.
;слова в строке могут быть разделены пробелами и знаками препинания.
;удалить в каждом слове строки повторяющиесЯ в нем буквы.

.model small
.data
;структура для ввода строки по функции 0ah
max db 80 ;максимальная длина строки
len db 0 ;реальная длина введенной строки
string db 80 dup (0) ;сама строка, заканчивается кодом 0dh

sEnter db 'Enter string: $'
sResult db 0dh,0ah,'Result : $'
sAny db 0dh,0ah,'Press any key$'

.code
start:
mov ax, @data ;настроим сегментные регистры
mov ds, ax
mov es, ax

;ввод строки
;введенная строка в структуре max,len,string
call EnterString

;решаем задачу
call DelRepeats

;выводим преобразованную строку
lea dx, sResult ;выведем Result:
mov ah, 9
int 21h

lea dx, string ;строка
mov ah, 9
int 21h

Exit: ;выход
lea dx, sAny
mov ah, 9
int 21h

mov ah, 0 ;подождем нажатия на любую клавишу
int 16h

mov ax, 4c00h
int 21h

EnterString proc ;ввод строки
lea dx, sEnter ;выведем приглашение
mov ah, 9
int 21h

lea dx, max ;вводим строку
mov ah, 0ah
int 21h
ret
EnterString endp

isLetter proc ;проверка на букву
cmp al, 'A' ;считаем, что буквы - только английские!
jb not_letter ; большие и маленькие
cmp al, 'Z'
jbe letter
cmp al, 'a'
jb not_letter
cmp al, 'z'
ja not_letter
letter:
inc bp ;помечаем, что найдена буква очередного слова
stc ;помечаем, что буква
ret
not_letter:
clc ;не буква
ret
isLetter endp

;поиск и обнуление повторяющихся букв в слове
;BX - адрес начала слова
;SI - адрес за словом
isRepeat proc
test bp, bp ;было ли слово?
jne isRepeat_ext_loop
ret ;повтор разделителей, которые не трогаем
isRepeat_ext_loop: ;будем искать все буквы слова с начала слова
; во всех последующих
cmp bx, si ;дошли до конца слова?
jae isRepeat_ret ;на выход
mov al, [bx] ;очередная буква
cmp al, 0 ;уже обнуленную пропускаем
je isRepeat_ext_next
lea di, [bx+1] ;со следующего адреса
isRepeat_int_loop:
cmp di, si ;до конца слова
jae isRepeat_ext_next
cmp al, [di] ;сравниваем
jne isRepeat_int_next
mov byte ptr[bx], 0 ;одинаковые обнуляем!
mov byte ptr[di], 0
isRepeat_int_next:
inc di ;на следующий адрес
jmp isRepeat_int_loop
isRepeat_ext_next:
inc bx ;на адрес следующей буквы, которую будем искать
jmp isRepeat_ext_loop
isRepeat_ret:
xor bp, bp ;сбросим флаг найденного слова
ret
isRepeat endp

DelZeros proc ;сожмем строку, выбросим все нулевые байты
lea si, string ;адрес начала строки
DelZeros_loop:
mov al, [si]
inc si
cmp al, '$'
je DelZeros_ret ;дошли до конца строки
cmp al, 0
jne DelZeros_loop ;ненулевые обходим
mov di, si ;адрес за нулевым байтом
DelZeros_shift_loop: ;сдвигаем строку на одну букву назад
mov al, [di] ;тем самым затираем нуль
mov [di-1], al
inc di
cmp al, '$' ;до конца строки
jne DelZeros_shift_loop
dec si ;на одну букву сдвинули назад, поэтому надо проверить
; символ на позиции бывшего нуля
jmp DelZeros_loop ;на проверку очередного символа
DelZeros_ret:
ret
DelZeros endp

DelRepeats proc ;удаление букв, которые повторяются в словах
lea si, string ;адрес начала строки
xor bx, bx ;вставим в конец строки символ '$' (для функции 9)
mov bl, len ;длина строки
mov [bx+si], byte ptr '$'
xor bp, bp ;флаг отсутствия слова
words_loop: ;цикл по словам
mov bx, si ;запоминаем начало слова
word_loop: ;поиск слова
mov al, [si]
inc si
cmp al, '$' ;дошли до конца
je DelRepeat_ret
call isLetter ;буква?
jc word_loop ;да - ищем небукву
;нет - конец слова
dec si ;si - адрес за разделителем, уменьшим на 1
; чтобы был адрес за словом
call isRepeat ;обнуляем повторы букв в слове (если они есть)
inc si ;адрес - за первым разделителем
jmp words_loop ;на поиск следующего слова
DelRepeat_ret: ;в конце надо еще проверить на наличие слова перед '$'
dec si
call isRepeat ;проверяем последнее слово
call DelZeros ;удаляем нулевые байты в строке
ret
DelRepeats endp

end start ;точка входа
[/code]
5
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
400167
1
08.04.2016, 19:39
общий
Адресаты:
Огромное спасибо за столь скорый ответ! Дай Бог здоровья!
давно
Посетитель
7438
7205
08.04.2016, 19:57
общий
Адресаты:
Да пожалуйста! Заходите еще
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа