Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [ASM] Задача на строки 
:(
    Опции темы
octopus
Дата 4.11.2010, 00:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 17.9.2010

Репутация: нет
Всего: нет



Господа программисты! Была бы очень признательна, если бы Вы помогли с задачкой! Не предстваляю, как организовать подобное на Ассемблере... smile   А надо...Вы моя последняя надежда!
Суть задачи: Дан массив запрещенных слов и предложение, в котором могут быть(или не быть) эти самые слова. Нужно удалить слова из предложения. Можно использовать 2 строки(2ая для результата). Также можно потребовать точку, как признак конца исходного предложения. 
Заранее спасибо!
PM MAIL   Вверх
iff
Дата 5.11.2010, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Администратор
**


Профиль
Группа: Участник
Сообщений: 949
Регистрация: 23.3.2007

Репутация: 3
Всего: 16



Какая ОС? Компилятор? Процессор?


Для DOS, компиятор TASM, процессор Intel 8086+
Код

    .MODEL    SMALL
    .STACK    32H
    .DATA

DELIMITER    DB    ' .,?!;:-', 0DH, 0AH, 09H
DELIMITERL    DW    $ - OFFSET DELIMITER    ;*

MASS    LABEL    BYTE    ;*
E1    DB    'QWERTY'
E2    DB    'ASD'
E3    DB    'FGG'
E4    DB    'KKL'
MASSEND    LABEL    BYTE    ;*

MASSL    DB    OFFSET E2 - OFFSET MASS
    DB    OFFSET E3 - OFFSET E2
    DB    OFFSET E4 - OFFSET E3
    DB    OFFSET MASSEND - OFFSET E4

MASSADR    DW    OFFSET E1
    DW    OFFSET E2
    DW    OFFSET E3
    DW    OFFSET E4

MASSLE    DW    4

OLDSINDEX    DW    OFFSET STRIN    ;*
MASSINDEX    DW    0    ;*

NEWLINE    DB    0DH, 0AH, '$'    ;*

INPUTBUFER    LABEL    BYTE    ;*
MAXLEN    DB    0FFH    ;*
LEN    DB    ?    ;*
STRIN    DB    0FFH DUP (?)    ;*

    .CODE
MAIN:
    MOV    AX,@DATA    ;Инициализация сегмента данных
    MOV    DS,AX
    MOV    ES,AX

    MOV    AH,0AH    ;Ввод строки
    LEA    DX,INPUTBUFER
    INT    21H
;===============================Найти разделитель===========================================
NEWS:
    MOV    DI,OLDSINDEX    ;Найти разделитель в предложении
S10:    MOV    CX,DELIMITERL    ;Цикл для всех разделителей
    LEA    SI,DELIMITER
S20:    LODSB
    CMP    AL,[DI]
    JE    NEWE
    LOOP    S20
    INC    DI    ;Следующий символ в строке
    JMP    S10
;=================================Сравнить слова=============================================
NEWE:
    ;DI указывает на разделитель после слова. OLDSINDEX - начало слова.
    PUSH    DI
    MOV    CX,DI
    SUB    CX,OLDSINDEX    ;CX - длина слова из текста
    MOV    BX,MASSINDEX
    CMP    CL,MASSL[BX]    ;Сравнить с длиной элемента
    JNE    NEXT    ;Если не равно то след. элем.
    
    MOV    DI,OLDSINDEX    ;Если ровно, то сравнить слова
    SHL    BX,1
    MOV    SI,MASSADR[BX]    ;MASSADR[BX*2]
    CLD
    REPE CMPSB
    JNE    NEXT    ;Если не равны, то след. элем.
            ;Если равны, то удалить

;====================================Удалить===============================================
    ;DI указывает на разделитель после слова. OLDSINDEX - начало слова.
    MOV    CX,DI    ;Заменить "*"
    SUB    CX,OLDSINDEX
    MOV    DI,OLDSINDEX
    MOV    AL,'*'
    CLD
    REP STOSB
;======================================Конец цикла=========================================
NEXT:    POP    DI
    INC    MASSINDEX    ;Следующий элемент массива
    MOV    AX,MASSLE
    CMP    AX,MASSINDEX    ;Если прошли все элементы,
    JNE    NEWE

    MOV    AL,LEN    ; то следующее слово в строке
    XOR    AH,AH
    ADD    AX,OFFSET STRIN
    CMP    AX,DI    ;Если строка закончилась
    JE    EXIT    ; то выход

    INC    DI
    MOV    OLDSINDEX,DI
    MOV    MASSINDEX,0
    JMP    NEWS
;==================================Вывод на экран и выход================================
EXIT:    MOV    BL,LEN    ;В конце строки поставить "$"
    XOR    BH,BH
    ADD    BX,OFFSET STRIN
    MOV    BYTE PTR [BX],'$'
    
    MOV    AH,09H    ;Перевод строки на дисплее
    LEA    DX,NEWLINE
    INT    21H
    
    LEA    DX,STRIN    ;Вывод результата
    INT    21H
    
    LEA    DX,NEWLINE    ;Перевод строки на дисплее
    INT    21H

    MOV    AX,4C00H    ;Выход
    INT    21H
    END    MAIN


Элементы данных, помеченыые ";*" изменять не рекомендуется. Программа работает так:
1)запрашивает ввод с клавиатуры строки,
2)запрещенные слова заменяет на звездочки.
3) выводит на экран результат

Запрещенные слова указаны в массиве MASS, их количество в переменной MASSLE, их длины в массиве MASSL, их адреса в массиве MASSADR.
В переменной DELIMITER указаны символы, которые считаются разделителями слов в предложении.

Добавлено через 2 минуты и 33 секунды
П. С. У этой программы есть минус: она чувствительна к регистру. Т.е. слово QWERTY будет заменено на звездочки, а Qwerty - нет.


--------------------
DOS... Синей пеленой экран заполнил чистый DOS 
Мышь... Стала вдруг квадратной, потеряла форму мышь... 
Я разбил окно, девяностопятое мастдайное окно, 
И поставил DOS, и тогда увидел: Это счастье, — вот оно.  
PM MAIL WWW   Вверх
octopus
Дата 8.11.2010, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 17.9.2010

Репутация: нет
Всего: нет



)) Все именно так)) Спасибо огромное. реализация...ммм...потрясная) я-то хотела кучу процедур делать, да все никак подступиться не могла...Спасибо!
один только вопрос. 0DH, 0AH это ж новая строка. а по нажатию ентера она вводится в программу, если так можно выразится. т.е. эта программа расчитана для работы с файлами? или я чего-то не понимаю?

Еще раз спасибо. Просто спасли!))
PM MAIL   Вверх
iff
Дата 8.11.2010, 21:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Администратор
**


Профиль
Группа: Участник
Сообщений: 949
Регистрация: 23.3.2007

Репутация: 3
Всего: 16



Цитата(octopus @  8.11.2010,  19:26 Найти цитируемый пост)
один только вопрос. 0DH, 0AH это ж новая строка.

Вы имеете ввиду что выводится 0DH, 0AH перед выводом результата и после него?
Да, это перевод строки. На экране. Когда мы воводим 0DH, 0AH курсор переходит на начало следующей строки.


--------------------
DOS... Синей пеленой экран заполнил чистый DOS 
Мышь... Стала вдруг квадратной, потеряла форму мышь... 
Я разбил окно, девяностопятое мастдайное окно, 
И поставил DOS, и тогда увидел: Это счастье, — вот оно.  
PM MAIL WWW   Вверх
octopus
Дата 9.11.2010, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 17.9.2010

Репутация: нет
Всего: нет



)) Спасибо, не сразу поняла.
Я, как порядочная, хотела сама удаление организовать, да видно не судьба. Вот то, что у меня получилось. Тут есть ошибки, но предыдущие варианты либо циклились, либо толку от них не было... 
Код

;====================================Удалить===============================================
 ;DI указывает на разделитель после слова. OLDSINDEX - начало слова.
 ; DI - адрес смещения строки-источика, надо бы его в СИ
 ; в DI надо бы адрес смещения строки-приемника, т.е. DEST, (DEST db 255 dub(?))
 ; в СХ длина пересылаемого элемента строки.
 push CX
 mov DI, DESTPOS
 mov SI, DI
 mov CX, LEN  ; CX - length of STRIN
 sub DI, offset STRIN 
 add DI,2
 sub CX, DI
 
 rep MOVS DEST, STRIN 
 pop CX
 

Жду комментариев))) Спасибо.

ЗЫ еще вопрос. столкнулась с проблемой: через командную строку все замечательно работает, а вот через эмулятор(emu8086 4.00b7) никакого эффекта. с чем это может быть связано?

Это сообщение отредактировал(а) octopus - 9.11.2010, 21:12
PM MAIL   Вверх
iff
Дата 10.11.2010, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Администратор
**


Профиль
Группа: Участник
Сообщений: 949
Регистрация: 23.3.2007

Репутация: 3
Всего: 16



Цитата(octopus @  9.11.2010,  21:11 Найти цитируемый пост)
через командную строку все замечательно работает, а вот через эмулятор(emu8086 4.00b7) никакого эффекта.

Значит в эмуляторе ошибка.

Цитата(octopus @  9.11.2010,  21:11 Найти цитируемый пост)
Я, как порядочная, хотела сама удаление организовать, да видно не судьба.

Вы хотите именно удалить? По-мойму горазду лучше (и не потому что проще smile ) не удалять, а заменять звездочками. Потому, что если из предложения бесследно выкинуть слово, то смысл самого предложения может потеряться, а вот если заменить его звездочками, или к примеру на его места поставить значок "<...>", тогда читающий поймет, что здесь пропущено слово, и тогда смысл предложения не разрушится.
Например, вы ввели в программу: "Несколько лет тому назад в одном из своих поместий жил старинный русской барин, Кирила Петрович Троекуров." А запрещенным словом пусть будет "жил". Если просто удалять запрещенные слова, то получится: "Несколько лет тому назад в одном из своих поместий старинный русской барин, Кирила Петрович Троекуров.", а если заменять звездочками, то получится "Несколько лет тому назад в одном из своих поместий *** старинный русской барин, Кирила Петрович Троекуров." Согласитесь, второй случай читать легче.


--------------------
DOS... Синей пеленой экран заполнил чистый DOS 
Мышь... Стала вдруг квадратной, потеряла форму мышь... 
Я разбил окно, девяностопятое мастдайное окно, 
И поставил DOS, и тогда увидел: Это счастье, — вот оно.  
PM MAIL WWW   Вверх
octopus
Дата 10.11.2010, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 17.9.2010

Репутация: нет
Всего: нет



Так-то оно так. Но если подходить к лабе с этой стороны, то пусть это будет фильтр сообщений в чате, где некоторые могут позволить себе лексические вольности(а в массиве как раз эти вольности и содержатся))) тогда удаление вполне оправданно, особенно если публика чувствительная...
По правде говоря, задание состоит в том, чтобы УДАЛИТЬ запрещенные слова. Как видите, мне не удается это сделать самостоятельно((( 
А именно, почему в 9 строке компилятор выдает ошибку? в предыдущем блоке была такая же по смыслу операция...
PM MAIL   Вверх
iff
Дата 10.11.2010, 22:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Администратор
**


Профиль
Группа: Участник
Сообщений: 949
Регистрация: 23.3.2007

Репутация: 3
Всего: 16



1) ошибку выдает из-за того что CX - слово, а LEN - байт.
2) 
Цитата(octopus @  10.11.2010,  20:28 Найти цитируемый пост)
 Но если подходить к лабе с этой стороны, то пусть это будет фильтр сообщений в чате, где некоторые могут позволить себе лексические вольности(а в массиве как раз эти вольности и содержатся))) тогда удаление вполне оправданно, особенно если публика чувствительная...

в данном случае удалить и "замазать" (заменить на символ "*") - это синонимы.

Но если хотите все таки сделать так что слово имменно бесследно исчезает из текста, то вот иллюстация:
user posted image
Это строка длинной 7 которая начинается со смещения 0; а нужно удалить подстроку длинной 2, которая начинается со смещения 2
Мы видим, что при использовании reb movsb, мы должны:
 а) инициализировать SI как смещение основной строки+смещение удаляемой подстроки+длина подстроки.
в данном случае 0+2+2=4.
 б) DI инициализировать как адрес начала удаляемой подстроки (в данном случае 2)
 в) в CX поместить смещение основной строки+длина основной строки-смещение удаляемой подстроки-длина удаляемой подстроки. В данном случае 0+7-2-2=3.
 г) незабудте переменную LEN уменьшить на длину удаляемой подстроки.


--------------------
DOS... Синей пеленой экран заполнил чистый DOS 
Мышь... Стала вдруг квадратной, потеряла форму мышь... 
Я разбил окно, девяностопятое мастдайное окно, 
И поставил DOS, и тогда увидел: Это счастье, — вот оно.  
PM MAIL WWW   Вверх
octopus
Дата 16.11.2010, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 17.9.2010

Репутация: нет
Всего: нет



Спасибо!!
PM MAIL   Вверх
octopus
Дата 30.11.2010, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 17.9.2010

Репутация: нет
Всего: нет



Да! На всякий случай, для тех, кому вдруг понадобится именно удаление!
этот кусок кода удаляет слово вместе с пробелами после него. 
Код

;====================================Удалить===============================================
    ;DI указывает на разделитель после слова. OLDSINDEX - начало слова.
;++++++++++++++++++++++++++++++++++++++++++++++=
push ax
space:
 mov ax, [di]
 cmp al, 32
 jne continue
 inc di
 jmp space
continue:
;++++++++++++++++++++++++++++++++++++++++++++++=

    mov    CX,DI            
    sub    CX,OLDSINDEX
   
    mov AX, CX               ; в АХ длина слова с пробелами

    lea CX, STRIN
    mov DI, OLDSINDEX
    sub DI, CX                ;  в ДИ смещение начала слова относительно начала предложения
  
    add di, ax                 ; смещение конца слова относительно предложения
    xor cx, cx
    mov cl, STRIN[1]       ; длина предложения
    sub cx, di                  ; длина оставшейся части предложения
    INC cx
    mov di, OLDSINDEX  ; абсолютное смещение начала слова
    
    push si      
    mov si, di                ;
    add si, ax               ; абсолютное смещение конца слова

    cld
    rep movsb
    
    pop si
    sub len, al              ; уменьшение количества символов в предложении
    pop ax
    mov OLDSINDEX, offset STRIN
    pop di
    mov di, OLDSINDEX
    jmp news


Добавлено через 29 секунд
может, не самая лучшая реализация, но я старалась)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0890 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.