На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Запрещается обсуждать написание вирусов, троянов и других вредоносных программ!
2. Помните, что у нас есть FAQ раздела Assembler и Полезные ссылки. Посмотрите, возможно, там уже имеется решение вашего вопроса.

3. Настоятельно рекомендуем обратить особое внимание на правила форума, которые нарушаются чаще всего:
  3.1. Заголовок темы должен кратко отражать её суть. Темы с заголовками типа "Срочно помогите!" или "Ассемблер" будут отправляться в Корзину для мусора.
  3.2. Исходники программ обязательно выделяйте тегами [code]...[/code] (одиночные инструкции можно не выделять).
  3.3. Нежелательно поднимать старые темы (не обновлявшиеся более года) без веской на то причины.

Не забывайте также про главные Правила форума!

Добро пожаловать и приятного вам общения!!! ;)
 
Модераторы: Jin X, Qraizer
Страницы: (3) [1] 2 3  все  ( Перейти к последнему сообщению )  
> Поиск одинаковых слов в строках , Вопрос по TASM
    Всем привет!
    Есть код из книги Юрова по ассемблеру
    ExpandedWrap disabled
      ;prg_12_4.asm
      MASM
      MODEL   small
      STACK   256
      .data
      ;строки для сравнения
      string1 db  'Поиск символа в этой строке.',0ah,0dh,'$'
      string2 db  'Поиск символа не в этой строке.',0ah,0dh,'$'
      mes_eq  db  'Строки совпадают.',0ah,0dh,'$'
      fnd db  'Несовпавший элемент в регистре al',0ah,0dh,'$'
      .code
      ;привязка ds и es к сегменту данных
      assume ds:@data,es:@data
      main:
          mov ax,@data    ;загрузка сегментных регистров
          mov ds,ax
          mov es,ax       ;настройка es на ds
          mov ah,09h
          lea dx,string1
          int 21h ;вывод string1
          lea dx,string2
          int 21h ;вывод string2
          cld     ;сброс флага df
          lea di,string1  ;загрузка в es:di смещения
      ;строки string1
          lea si,string2  ;загрузка в ds:si смещения
      ;строки string2
          mov cx,29   ;для префикса repe - длина строки
      ;поиск в строке (пока нужный символ и символ в строке не равны)
      ;выход - при первом несовпавшем
      repe    cmps    string1,string2
          jcxz    eql ;если равны - переход на eql
          jmp no_eq   ;если не равны - переход на no_eq
      eql:        ;выводим сообщение о совпадении строк
          mov ah,09h
          lea dx,mes_eq
          int 21h ;вывод сообщения mes_eq
          jmp exit        ;на выход
      no_eq:      ;обработка несовпадения элементов
          mov ah,09h
          lea dx,fnd
          int 21h ;вывод сообщения fnd
      ;теперь, чтобы извлечь несовпавший элемент из строки
      ;в регистр-аккумулятор,
      ;уменьшаем значение регистра si и тем самым перемещаемся
      ;к действительной позиции элемента в строке
          dec si  ;команда lods использует ds:si-адресацию
      ;теперь ds:si указывает на позицию в string2
          lods    string2 ;загрузим элемент из строки в AL
      ;нетрудно догадаться, что в нашем примере это символ - "н"
      exit:       ;выход
          mov ax,4c00h
          int 21h
      end main


    Результатом его работы является первая символ (подстрока), который не совпадает со строкой образцом. Он заносится в регистр AL, это понятно.
    А как нужно изменить данный код таким образом, чтобы он выводил все подстроки (слова) данной строки, которые одинаковы для обеих строк?
    Не соображу :crazy:
      Цитата APleskan @
      чтобы он выводил все подстроки (слова) данной строки, которые одинаковы для обеих строк

      Нипанятна... покажите хотя бы эталонный вывод для строк из кода.
        Проще говоря нужно сравнить две строки на предмет нахождения в них одинаковых слов.
        Вот так :D
          Понятнее не стало. Покажи, что хочешь получить на экране, если в код внести нужные тебе исправления.

          В текущем виде при запуске должно получиться нечто вроде:
          ExpandedWrap disabled
            c:\> prg_12_4
             
            Поиск символа в этой строке.
            Поиск символа не в этой строке.
            Несовпавший элемент в регистре al
             
            c:\>
            Этот выхлоп есть. Нужно получить, например, для двух строк: красное яблоко и зелёное яблоко результат яблоко.
            :)

            P.S. Понятно, что лучше городить макросы, но как это делать для таких динозавров я давно и основательно позабыл :-?
            Сообщение отредактировано: APleskan -
              Это будет совсем другой код :)
              В общих чертах: перебираешь каждое слово первой строки и ищешь эти слова во второй. Если нашёл, выводишь :)
                Насколько я понимаю, без разбиения на отдельные процедуры здесь не обойтись?
                  Я бы сделал так:
                  ExpandedWrap disabled
                    String1 db 'Hello my big boss!',0
                    String2 db 'Good bye my little boss!',0
                    First dw String1
                    Second dw String2
                  First - текущая позиция строки String1, Second - строки String2.
                  И дальше нужна процедура NextWord, которая переходит к следующему слову (в регистре BX, скажем, ей передаётся адрес переменной с текущей позицией строки), т.е.:
                  ExpandedWrap disabled
                    CompareNext:
                      . . .
                      lea bx,First
                      call NextWord
                      jnc CompareNext
                    . . .
                    NextWord proc
                      mov si,[bx]
                    . . .
                  процедура будет переходить к следующему слову (т.е. пропускать сначала все буквенные символы, затем все небуквенные). Если встретит в итоге 0 (конец строки), вернёт флаг CF=1 (stc), иначе CF=0 (clc).

                  Ну и нужна будет функция, сравнивающая оба слова (из First и Second) и ещё процедура, выводящая текущее слово (из First) + пробел.
                    Спасибо за наводку. Попробую довести до ума ;)
                      M

                      APleskan, кстати, тему надо называть не креативно, как роман, а соответственно сути вопроса!
                        На процедуры можно, конечно, не бить - но лапша же получится...

                        И учти, что для каждого слова первой строки тебе надо будет проверять совпадение со всеми словами второй строки. Так что начни с написания процедуры поиска одного слова в строке, а потом добавишь обвязку перебора слов.

                        И для упрощения я бы сначала в обеих строках заменил все разделители слов на некий один и тот же символ, который в строке гарантированно отсутствует. Совсем отлично, если это будет символ доллара - упростит вывод.
                          Всем спасибо за ответы.

                          У меня обширная электронная библиотека. Есть еще Ирвин Кип, ;) так что, в любом случае чего-нибудь да сварганю :rolleyes:

                          Добавлено
                          Кстати да, я старею. У того же Юрова в "Практикуме" есть решение похожей задачи 8-)
                          Jin X можете сносить тред :ph34r:
                            Оставлю здесь частное решение задачи, авось кому-то пригодится :)
                            ExpandedWrap disabled
                              ;--------------------------------------------------------------------------------;
                              ;search.asm - поиск строки P в строке S. Длина S фиксирована.
                              ;Вход: S и P - массивы символов размером N и M байт (M=<N).
                              ;Выход: сообщение о количестве вхождений строки P в строку S.
                              ;--------------------------------------------------------------------------------;
                              masm
                              model small
                              .data
                              ;задаем массив S
                              s   db  "яблоко красное, зеленое яблоко, яблоко сладкое, кислое яблоко, яблоко летнее, спелое яблоко"
                              Len_S=$-s
                                  Db  "$"
                              mes db  "Вхождений строки - "
                              ;задаем массив P - аргумент поиска
                              p   db  "зеленое яблоко"
                              Len_P=$-p
                                  db  " - "
                              Count   db  0,"$"   ;счетчик вхождений P в S
                              .stack  256
                              .486
                              .code
                              main:
                                  mov dx,@data
                                  mov ds,dx
                              push    ds
                              pop es
                                  cld
                                  mov cx,len_s
                                  lea di,s
                                  mov al,p    ;P[0]->al
                              next_search:
                                  lea si,p
                                  inc si  ;на следующий символ
                              repne   scasb
                                  jcxz    exit
                              push    cx
                                  mov cx,len_p-1
                              repe    cmpsb
                                  jz  eq_substr
                              ;строка p <> подстроке в s
                                  mov bx,len_p-1
                                  sub bx,cx
                              pop cx
                                  sub cx,bx   ;учли пройденное при сравнении cmpsb
                                  jmp next_search
                              eq_substr:
                              ;далее можно выйти, если поиск однократный, но мы упорные, поэтому продолжаем
                              pop cx
                                  sub cx,len_p-1  ;учли пройденное при сравнении cmpsb
                                  inc count
                                  jmp next_search
                               
                              exit:  
                                  add count,30h ;преобразуем число в строку
                                  lea dx,mes
                                  mov ah,9h
                                  int 21h
                                  
                              ;выход
                                  mov ax,4c00h
                                  int 21h
                              end main

                            Доработка приветствуется :thanks:
                              ExpandedWrap disabled
                                s db 15 dup("aa ")
                                ...
                                p db "aa"
                              Упс...

                              ExpandedWrap disabled
                                s db "ababac"
                                ...
                                p db "abaс"
                              Упс-2...

                              ExpandedWrap disabled
                                        mov     dx,@data
                                        mov     ds,dx
                                push    ds
                                pop     es

                              А почему не
                              ExpandedWrap disabled
                                        mov     dx,@data
                                        mov     ds,dx
                                        mov     es,dx
                              ?

                              И за каким тут
                              ExpandedWrap disabled
                                .486
                              ?
                                Можно смоделировать 2-х проходной алгоритм:

                                1) Находится первый, последний символ текущего слова и расстояние (длина слова) в первой строке
                                2) Ищется тоже самое во второй строке
                                3) Если все совпадает - вторым проходом сравниваются слова на полное совпадение

                                Во многих случаях - можно получить прирост скорости сравнения. Т.к. получается некое подобие сравнивания не данных, а такого вот примитивного хэша. Естественно - в некоторых случаях это может наоборот притормозить. Чуйка подсказывает, что для обработки естественного текста подход будет полезен.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) [1] 2 3  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0418 ]   [ 16 queries used ]   [ Generated: 19.04.24, 23:27 GMT ]