83 / 19 / 5
Регистрация: 01.02.2015
Сообщений: 655
1

Поиск первого вхождения одной строки в другую

17.02.2016, 19:15. Показов 2095. Ответов 9
Метки нет (Все метки)

Здравствуйте уважаемые форумчане!
Необходимо написать программу которая производит поиск первого вхождения строки-отправителя в строку-получатель и возвращает соответствующую позицию. Входные параметры: DS:SI указывают на строку-отправитель, а ESI указывают на строку-получатель.
вот собственно сам код ВЕСЬ
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
data segment  
otvet        db  2 dup (0),'$'     
mes1         db  13,10,'net sootvetstvii$'
mes2         db  13,10,'sovpadenie s elentom $'
bufIshodnii  db  'afadfafaafafs54'
lenIshodnii  db  ($ - bufIshodnii)-1
req          db  10,13,'Enter string:$'
inpbuf       db  30      
lenVvoda     db  ?       
bufVvoda     db  30 dup (?)      
ends
 
stek segment stack 'stack'
    dw   128  dup(0)
ends
 
code segment
assume cs:code
start:
; set segment registers:
    mov ax, data
    mov ds, ax
    mov es, ax
    
    mov  ah, 09h
    lea  dx, req
    int  21h
 
    mov ah, 0Ah
    lea dx, inpbuf      
    int 21h     
    
    XOR DX,DX
    xor ch,ch
    lea si,bufVvoda
    lea di,bufIshodnii
    mov cl,lenIshodnii
    PUSH CX
;poisk
cycle1:
    XOR BX,BX
    MOV cl,lenVvoda
    rep cmpsb
    JZ  sovpadenie ;esle ravnie to => 
    CMP CX,0
    JZ  odin
    MOV Bl,lenVvoda
    SUB BX,CX
    JMP boleeOdnogo
odin:     
    POP CX
    CMP lenVvoda,1
    JZ  dallee
    SUB DI,1
dallee:    
    SUB cl,1
    JC  EndStroki    ;CF=1
    add dx,1
    JMP konec
boleeOdnogo: 
    POP CX
    SUB CX,BX
    JC  EndStroki    ;CF=1    
konec:        
    PUSH CX
    lea si,bufVvoda
    JMP cycle1 
EndStroki:
    mov ah,09h
    LEA dx,mes1
    INT 21h
    JMP ProgramEnd
sovpadenie:
    POP CX 
    MOV BH,lenVvoda
    SUB cl,bh
    MOV Bl,lenIshodnii
    SUB Bl,cl
    CMP DX,0
    JNZ  nedellit 
   SUB Bl,lenVvoda
nedellit:   
    ADD BL,48
    MOV otvet,Bl
    MOV ah,09h
    lea dx,mes2
    int 21h
    MOV ah,09h
    lea dx,otvet
    int 21h    
ProgramEnd: 
    mov ax, 4c00h ; exit to operating system.
    int 21h    
ends
 
end start
а вот здесь оснавная часть программы (без ввода и вывода)
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
cycle1:
    XOR BX,BX
    MOV cl,lenVvoda
    rep cmpsb
    JZ  sovpadenie ;esle ravnie to => 
    CMP CX,0
    JZ  odin
    MOV Bl,lenVvoda
    SUB BX,CX
    JMP boleeOdnogo
odin:     
    POP CX
    CMP lenVvoda,1
    JZ  dallee
    SUB DI,1
dallee:    
    SUB cl,1
    JC  EndStroki    ;CF=1
    add dx,1
    JMP konec
boleeOdnogo: 
    POP CX
    SUB CX,BX
    JC  EndStroki    ;CF=1    
konec:        
    PUSH CX
    lea si,bufVvoda
    JMP cycle1
Программа работает но не знаю как сделать что бы определяло позицию (постоянно недочёты)
МБ кто-нибудь знает как написать, мб хотя бы алгоритм программы
Как определить номер элемента с которого начинаются повторения
МБ есть похожие программы буду рад любому содействию!
ПРИМЕР РАБОТЫ ПРОГРАММЫ
есть уже строка например 123qwe123
ввожу например qwe
а оно мне выдаёт 3 позиция
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.02.2016, 19:15
Ответы с готовыми решениями:

Поиск первого вхождения символа в строку
Процедура Str_scan производит сканирование строки для поиска первого вхождения определенного...

Поиск подстроки в строке и индекс первого вхождения
Доброго времени суток! Как осуществляется поиск подстроки? Весь день пытался придумать, облазил...

[masm32] Поиск и замена первого вхождения символа в строку
Здравствуйте. Господа программисты, есть код написанный мной при помощи masm32 под windows, вот я...

Вхождение элементов одной строки в другую
Нужно проверить входит ли элемент одной строки в другую. Не понятно как сделать цикл в цикле, ведь...

9
183 / 121 / 26
Регистрация: 18.05.2015
Сообщений: 509
17.02.2016, 20:12 2
найти подстроку в строке?
ну так правильно cmpsb только один указатель стоит другой плывет вдоль
1
3402 / 1821 / 489
Регистрация: 28.02.2015
Сообщений: 3,699
17.02.2016, 20:14 3
1)ищите первый символ введенной строки;
2)запоминаете индекс;
3)проверяете введенную строку на вхождение.
1
Эксперт быдлокодинга
2087 / 521 / 69
Регистрация: 04.11.2010
Сообщений: 1,310
17.02.2016, 22:54 4
Shura_deg, добавлю к следующему.

Цитата Сообщение от Constantin Cat Посмотреть сообщение
1)ищите первый символ введенной строки;
2)запоминаете индекс;
3)проверяете введенную строку на вхождение.
По первому пункту почитайте на счёт команды SCAS и префикс REP и его модификации
По третьему пункту команду CMPS с тем же префиксом что указан в п. 1 Так же для треьбего пункта будет полезен пункт ноль.
0) Вычислить длину подстроки
1
Эксперт Hardware
Эксперт Hardware
5406 / 1947 / 357
Регистрация: 29.07.2014
Сообщений: 2,863
Записей в блоге: 4
18.02.2016, 08:05 5
Лучший ответ Сообщение было отмечено Shura_deg как решение

Решение

Цитата Сообщение от Shura_deg Посмотреть сообщение
Входные параметры: DS:SI указывают на строку-отправитель, а ESI указывают на строку-получатель.

Не по теме:

Прикольный получатель получился. Прям как твой аватар..



Чтото букаф много в твоём коде.
Вот примерная реализация такой задачи. Объяснять не буду.., всё в комментах:

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
ORG  100h
JMP  start
 
mess0  DB  13,10,'    STRING: $'
mess1  DB  13,10,'SUB/STRING: $'
mess2  DB  13,10,' START POS: $'
mess3  DB  13,10,10,7,'NO RESULT! Press any key...$'
 
buf_1  DB  80,0,80 DUP(0)   ; буфер для строки
buf_2  DB  10 DUP(0)        ; буфер для под/строки
len_2  DW  0
 
start:
; сохраняем введённую строку: (fn) 0Ah ==============================//
   MOV   AH,9            ;
   MOV   DX,mess0        ;
   INT   21h             ;
   MOV   AH,0Ah          ;
   MOV   DX,buf_1        ;
   INT   21h             ;
 
; сохраняем под/строку =====: STOSB =================================//
   MOV   AH,9            ;
   MOV   DX,mess1        ;
   INT   21h             ;
   MOV   DI,buf_2        ;
@@:                      ;
   MOV   AH,1            ;
   INT   21h             ;
   CMP   AL,13           ; заканчиваем ввод по-ENTER
   JE    next            ;
   STOSB                 ;
   JMP   @b              ;
 
; вычисляем длину под/строки: SCASB =================================//
next:
   XOR   AX,AX           ; искать будем нуль в конце строки
   MOV   CX,0FFFFh       ; ставим счётчик на максимум
   MOV   DI,buf_2        ; где искать
   REPNE SCASB           ; поиск пошёл!
   NOT   CX              ; инверсия счётчика
   DEC   CX              ; CX = длина под/строки
   MOV   [len_2],CX      ; сохраняем её в переменной
 
; начинаем поиск под/строки в строке: CMPSB =========================//
   XOR   AX,AX            ; это будет "плавающая позиция" в строке
   XOR   BX,BX            ; это будет "финишная черта" для плавца
   MOV   BL,BYTE[buf_1+1] ; BX = длина строки
   SUB   BX,CX            ; оттяпаем лишний хвост
   XOR   DX,DX            ; это будет найденая позиция в строке
@@:                       ;
   MOV   SI,buf_1+2       ; SI указывает на строку
   MOV   DI,buf_2         ; DI - на под/строку
   MOV   CX,[len_2]       ; СХ = длина под/строки
   ADD   SI,AX            ; "плавающая позиция" в строке
   MOV   DX,SI            ; запоминаем эту позицию..
   REPE  CMPSB            ; сравниваем байт(DI) с байтом(SI)
   JZ    @10              ; переход, если есть вхождение под/строки
   INC   AX               ; иначе: позиция "поплыла" вперёд
   DEC   BX               ; ..а счётчик назад
   JNZ   @b               ; повторяем поиск с новой позиции..
; ошибка поиска! ====================================================//
   MOV   AH,9             ;
   MOV   DX,mess3         ; мессага!
   INT   21h              ;
   JMP   exit             ; ..и на выход!
 
; нашли под/строку в строке! ========================================//
; выводим позицию на экран: AAM, INT-29H ============================//
@10:                     ;
   DEC   DX              ; декремент позиции
   PUSH  DX              ; запомним её..
   MOV   AH,9            ; мессагу на экран
   MOV   DX,mess2        ;
   INT   21h             ;
   POP   AX              ; снимаем позицию в АХ
   MOV   BX,buf_1        ; ВХ = адрес начала строки
   SUB   AX,BX           ; вычисляем разницу
   AAM                   ; распаковываем АL в АХ
   ADD   AX,3030h        ; переводим число в символы
   XCHG  AH,AL           ; сперва выводим на экран старшую часть
   INT   29h             ;
   SHR   AX,8            ; теперь младшую часть
   INT   29h             ;
 
exit:                    ;
   XOR   AX,AX           ; выход!
   INT   16h             ;
   INT   20h             ;
2
3402 / 1821 / 489
Регистрация: 28.02.2015
Сообщений: 3,699
18.02.2016, 09:54 6
Цитата Сообщение от Полный 30h Посмотреть сообщение
По первому пункту...
По третьему пункт...

Цитата Сообщение от Shura_deg Посмотреть сообщение
мб хотя бы алгоритм программы
ТС просил хотябы алгоритм.
1
Эксперт быдлокодинга
2087 / 521 / 69
Регистрация: 04.11.2010
Сообщений: 1,310
18.02.2016, 17:18 7
Constantin Cat, мне проще программу написать за него, чем эти блоки и ромбики рисовать. К тому же не первый раз сталкиваюсь с ТС. Один из немногих кому действительно достаточно просто подсказать, а не расписывать от начала до конца. Да и не хочу отбирать у человека удовольствие от самостоятельно сделано работы.
0
3402 / 1821 / 489
Регистрация: 28.02.2015
Сообщений: 3,699
18.02.2016, 17:25 8
Цитата Сообщение от Полный 30h Посмотреть сообщение
Один из немногих кому действительно достаточно просто подсказать

Вот и я о томже.
0
83 / 19 / 5
Регистрация: 01.02.2015
Сообщений: 655
19.02.2016, 17:42  [ТС] 9
огромное спасибо Constantin Cat,за помощь как в решении задач, предоставлении интересных вариантов решения задач, а также помощи в составлении алгоритмов
также огромное спасибо Полный 30h, помогал в теоритических вопросах (помню задали весьма абстрактное задание на составление программ архитектуры фон Неймана), думал что никто, не поможет, но всё же нашлись добрые люди!, также за помощь в составлении алгоритма программы, в иной раз сижу и просто не могу понять с чего бы начать
Спасибо R71MT, за аригинальные алгоритмы задач, сам бы я до такого не додумался! Это как ответы в многих книгах по физике математике, мол реши сам, а потом сверься с тем как нужно решать, как сделать намного проще и оригинальней!

Добавлено через 22 часа 4 минуты
сделал под себя код R71MT,
выводил только до 10 теперь больше
сделал под эмулятор...8086, но нужно теперь будет приучаться к оболочке radasm с masm32 компилятором
может кто-то знает где найти толковую инструкцию как установить всё на вин хп??
вот сам получившийся код
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
data segment  
mes0         db  10,13,'Enter string:$'
mes1         db  10,13,'Enter chto iskat:$'    
mes2         db  13,10,'net sootvetstvii$'
mes3         db  13,10,'sovpadenie s elentom $'
inpbuf1      db  30      
lenStroki    db  ?       
bufStroki    db  30 dup (?)
inpbuf2      db  30      
lenPoisk     db  ?       
bufPoisk     db  30 dup (?)   
otvet        db  2 dup (0),'$'      
ends
 
stek segment stack 'stack'
    dw   128  dup(0)
ends
 
code segment
assume cs:code
start:
; set segment registers:
    mov ax, data
    mov ds, ax
    mov es, ax
    
    mov  ah, 09h
    lea  dx, mes0
    int  21h
 
    mov ah, 0Ah
    lea dx, inpbuf1      
    int 21h   
    
    mov  ah, 09h
    lea  dx, mes1
    int  21h
 
    mov ah, 0Ah
    lea dx, inpbuf2      
    int 21h         
    
    XOR CX,CX
    MOV Cl,lenPoisk       ;длина подстроки
; начинаем поиск под/строки в строке: CMPSB =========================//
   XOR   AX,AX            ; это будет "плавающая позиция" в строке
   XOR   BX,BX            ; это будет "финишная черта" для плавца
   MOV   BL,lenStroki     ; BX = длина строки
   SUB   BX,CX            ; оттяпаем лишний хвост
   XOR   DX,DX            ; это будет найденая позиция в строке
@@:                       ;
   LEA   SI,bufStroki     ; SI указывает на строку
   LEA   DI,bufPoisk      ; DI - на под/строку
   MOV   Cl,lenPoisk      ; СХ = длина под/строки
   ADD   SI,AX            ; "плавающая позиция" в строке
   MOV   DX,SI            ; запоминаем эту позицию..
   REPE  CMPSB            ; сравниваем байт(DI) с байтом(SI)
   JZ    @10              ; переход, если есть вхождение под/строки
   INC   AX               ; иначе: позиция "поплыла" вперёд
   DEC   BX               ; ..а счётчик назад
   JNS   @@                ; повторяем поиск с новой позиции..
; ошибка поиска! ====================================================//
   MOV   AH,9             ;
   LEA   DX,mes2         ; мессага!
   INT   21h              ;
   JMP   exit             ; ..и на выход!
 
; нашли под/строку в строке! ========================================//
; выводим позицию на экран: AAM, INT-29H ============================//
@10:
   mov otvet, al
   mov ah, 09h
   lea dx, mes3
   int 21h
   XOR AX,AX
   mov al,otvet
;вывод на экран
    XOR CX, CX
    MOV BX, 10
oi2:
    XOR DX, DX
    DIV BX 
    PUSH DX
    INC  CX
    TEST AX,AX
    JNZ  oi2
    MOV AH, 02H
oi3:
    POP DX
    CMP DL, 9
    JBE oi4
    ADD DL, 7
oi4:
    ADD DL, '0'
    INT 21H
    LOOP oi3         
exit: 
    mov ax, 4c00h ; exit to operating system.
    int 21h    
ends
 
end start
2
Модератор
Эксперт по электронике
8190 / 4117 / 1568
Регистрация: 01.02.2015
Сообщений: 12,724
Записей в блоге: 3
16.04.2017, 23:27 10
При попытке использовать код R71MT возникла ошибка Определить, входит ли в строку А подстрока Б?:
для строки "zxcdse" и подстроки "dse" результат поиска был отрицательный.

Основная причина - поиск, начинающийся с максимально правой позиции подстроки в строке начинается левее на 1 символ.
Исправление - добавить команду INC BX между 49 и 50 строками
Assembler
45
46
47
48
49
50
51
; начинаем поиск под/строки в строке: CMPSB =========================//
   XOR   AX,AX            ; это будет "плавающая позиция" в строке
   XOR   BX,BX            ; это будет "финишная черта" для плавца
   MOV   BL,BYTE[buf_1+1] ; BX = длина строки
   SUB   BX,CX            ; оттяпаем лишний хвост
   INC   BX
   XOR   DX,DX            ; это будет найденая позиция в строке
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.04.2017, 23:27
Помогаю со студенческими работами здесь

Копирование одной строки в другую через стек
Здравствуйте вы не могли бы мне помочь с реализацией небольшой программы, суть которой копирование...

Программа пересылки блока битов из одной строки в другую
Разработать программу пересылки блока битов из одной битовой строки (bit_str2 dd 012345678h) в...

Составить программу перессылки блока битов из одной битовой строки в другую
состтавте программу перессылки блока битов из одной битовой строки в (bit_str2 dd 012345678h)...

Программа копирует символы из строки str1 в строку str2 после первого вхождения буквы "a".
Пожалуйста помогите еще парочку задачек.:( 1 Найти ошибки в программе,объяснить их и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru