На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania 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 @
      чтобы он выводил все подстроки (слова) данной строки, которые одинаковы для обеих строк

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

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

            P.S. Понятно, что лучше городить макросы, но как это делать для таких динозавров я давно и основательно позабыл :-?
            Сообщение отредактировано: APleskan -
              Это будет совсем другой код :)
              В общих чертах: перебираешь каждое слово первой строки и ищешь эти слова во второй. Если нашёл, выводишь :)
              vpmultishiftqb vscatterpf0dps vfmsubadd132pd vgatherpf1dps vpclmulhqlqdq vcmptrue_ussd vaeskeygenassist
                Насколько я понимаю, без разбиения на отдельные процедуры здесь не обойтись?
                  Я бы сделал так:
                  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) + пробел.
                  vpmultishiftqb vscatterpf0dps vfmsubadd132pd vgatherpf1dps vpclmulhqlqdq vcmptrue_ussd vaeskeygenassist
                    Спасибо за наводку. Попробую довести до ума ;)
                      M

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

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

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

                          У меня обширная электронная библиотека. Есть еще Ирвин Кип, ;) так что, в любом случае чего-нибудь да сварганю :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
                              ?
                              Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
                              Есть претензии ко мне как к участнику? да ради бога.
                              Не нравятся мои ответы? не читайте их.
                              В общем, берегите себя. Нервные клетки не восстанавливаются.
                                Можно смоделировать 2-х проходной алгоритм:

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

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


                                Рейтинг@Mail.ru
                                [ Script Execution time: 0,1591 ]   [ 17 queries used ]   [ Generated: 16.10.18, 10:42 GMT ]