"Так" быстрее
G> Прощелкиваем всю строку. Запоминаем в массив номера позиций, в которой стоят пробелы. В конце цикла пишем в массив последним элементом длину строки. Затем находим попарные разности между элементами полученного массива и записываем рядом (все можно сделать в одном цикле). К примеру, получим что-то такое:
Гмм. А зачем это? В предыдущем решении все находится за один проход, а тут массивы какие то.
И потом где эти массивы находятся? Если в стэке или секции данных то вопрос а хватит ли их размера,
если в куче то надо еще ее выделять/освобождать.
Может ну его?
Подскажите пожелуйста как решить эту задачу:
Необходимо сделать функцию, которая делает следующее:
Дана строка слов разделённых пробелами, найти слово максимальной длинны.
Зараннее благодарен!
Здравствуйте, zeny, Вы писали:
Z>Подскажите пожелуйста как решить эту задачу: Z>Необходимо сделать функцию, которая делает следующее: Z>Дана строка слов разделённых пробелами, найти слово максимальной длинны. Z>Зараннее благодарен!
"В лоб", что называется, и решай.
1. Поставь указатель на начало строки.
2. Найди первый символ, не являющийся пробелом. Добаляй к адресу размер 1 символа в байтах, пока не наткнешся на пробел.
3. Как только наткнулся на пробел, количество добавленных на шаге (2) символов и есть длина очередной строки
4. Сравниваешь полученную на шаге (3) длину с длиной предыдущей строки. И если она больше, то сохрани значение указателя.
5. Если не достигнут конец строки, переходи на шаг (2)
6. Как только достигнут конец всей строки, сохраненный указатель будет содержать начало самой длинной подстроки.
Давненько я на ассемблере ничего не писал, но это может выглядеть примерно так:
mov di, offset _string ;в di загоняем адрес начала строки
xor bx,bx ;обнуляем bx - им будем индексировать
skip_spaces:
mov al, [di+bx] ;загружает первый символ строки
inc bx
cmp al, 020h ;пропускаем все
je skip_spaces ;ведущие пробелы
lea di, [di+bx-001h] ;загоняем в di адрес первой подстроки (di = di + bx - 1)
xor bx,bx
xor cx,cx ;в cx будем накапливать текущую наибольшую длину строки
next_char:
mov al, [di+bx]
inc bx
or al, al ;достигли конца строки?
jz exit
cmp al, 020h ;если не достигли пробела,
jne next_char ;то продолжаем считать длину текущей подстроки
exit:
cmp bx,cx ;длина текущей построки больше, чем предыдущей?
jna next_substring
mov cx,bx ;Если ДА, то сохраняем значение длины
mov si,di ;и указатель на эту подстроку
next_substring:
lea di, [di+bx-001h] ;переходим к следующему симаолу строки
or al,al ;достигли конца строки?
jnz skip_spaces ;если ДА, то выводим на печать самую длинную найденную подстроку
;на этом этапе в si находится начало самой длинной подстроки, а в cx - ее длина
;на экран ее можно вывести примерно так (хотя я тоже е уверен ибо многое забыл уже :) )
cld
mov ah,00Eh
print_char:
lodsb
int 010h
loop print_char
Этот код для ДОС-программы типа СОМ (те изначально CS=DS=ES=SS)
P.S. Это примерный код. Не гарантирую что он даже скомпилируется, ибо на асме не писал уже года 4
Здравствуйте, Dr_Sh0ck, Вы писали:
D_S>Здравствуйте, zeny, Вы писали: Z>>Подскажите пожелуйста как решить эту задачу: Z>>Необходимо сделать функцию, которая делает следующее: Z>>Дана строка слов разделённых пробелами, найти слово максимальной длинны. Z>>Зараннее благодарен!
D_S>"В лоб", что называется, и решай.
Нееее... D_S>1. Поставь указатель на начало строки.
Поскипал... D_S>6. Как только достигнут конец всей строки, сохраненный указатель будет содержать начало самой длинной подстроки.
Зачем так?
Прощелкиваем всю строку. Запоминаем в массив номера позиций, в которой стоят пробелы. В конце цикла пишем в массив последним элементом длину строки. Затем находим попарные разности между элементами полученного массива и записываем рядом (все можно сделать в одном цикле). К примеру, получим что-то такое:
Здравствуйте, glyph, Вы писали:
D_S>>"В лоб", что называется, и решай. G> Нееее...
Не надо мудрить, там где все просто
G>Прощелкиваем всю строку. Запоминаем в массив номера позиций, в которой стоят пробелы. В конце цикла пишем в массив последним элементом длину строки. Затем находим попарные разности между элементами полученного массива и записываем рядом (все можно сделать в одном цикле). К примеру, получим что-то такое:
Так было бы красивей, если бы ты заранее знал сколько элементов тебе понадобиться в таком массиве. Кроме того его еще хранить нужно где-то... Кроме того между подстроками может стоять не ожин пробел, а несколько... и т.д. и т.п.
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, glyph, Вы писали:
G>> Зачем так?
А>"Так" быстрее
Уверен?
G>> Прощелкиваем всю строку. Запоминаем в массив номера позиций, в которой стоят пробелы. В конце цикла пишем в массив последним элементом длину строки. Затем находим попарные разности между элементами полученного массива и записываем рядом (все можно сделать в одном цикле). К примеру, получим что-то такое:
А>Гмм. А зачем это? В предыдущем решении все находится за один проход, а тут массивы какие то.
А тут что, 10? Тут тоже все в одном цикле. В моем случае ты получишь длины всех слов и их положения внутри подстроки. В варианте Dr_Sh0k — самой длинной. А>И потом где эти массивы находятся? Если в стэке или секции данных то вопрос а хватит ли их размера, А>если в куче то надо еще ее выделять/освобождать. А>Может ну его?
Однозначно этот массив потребует места меньше чем, твоя строка.
А если внимательно прочитать оба поста, то станет ясным, что алгоритм одинаковый, просто я предлагаю подсчитывать длину слова не итерациями, а как разность между старым значением указателя на пробел и текущим. Ну, и итерирование по строке можно делать по stos. Или тебя вообще интересует мой вариант кода?
d Unknown Artist — Mano8703 d
Re[5]: Асемблер
От:
Аноним
Дата:
24.06.04 14:38
Оценка:
Здравствуйте, glyph, Вы писали:
А>>"Так" быстрее G> Уверен?
Вопрос риторический. Да — уверен...
А>>Гмм. А зачем это? В предыдущем решении все находится за один проход, а тут массивы какие то. G> А тут что, 10? Тут тоже все в одном цикле. В моем случае ты получишь длины всех слов и G> их положения внутри подстроки. В варианте Dr_Sh0k — самой длинной.
Если бы по условиям задачи надо было найти длины всех слов — базару нет был бы нужен и массив и пробег по нему.
G> А если внимательно прочитать оба поста, то станет ясным, что алгоритм одинаковый, G> просто я предлагаю подсчитывать длину слова не итерациями, а как разность между старым G> значением указателя на пробел и текущим. G> Ну, и итерирование по строке можно делать по stos. Или тебя вообще интересует мой вариант кода?
Здравствуйте, Dr_Sh0ck, Вы писали:
D_S>Так было бы красивей, если бы ты заранее знал сколько элементов тебе понадобиться в таком массиве. Кроме того его еще хранить нужно где-то... Кроме того между подстроками может стоять не ожин пробел, а несколько... и т.д. и т.п.
Ну, нам надо переехать в "Философию". Количество пробелов можно запросто оценить. Их будет не больше, чем длина строки. Определения термина "слово" не было, поэтому два пробела запросто можно считать как слово нулевой длины.
Короче, смысл не в этом.
Здравствуйте, Dr_Sh0ck, Вы писали:
D_S>>>"В лоб", что называется, и решай. G>> Нееее... D_S>Не надо мудрить, там где все просто
Я сегодня вечером посидел и решил, что да. С разностями ненужный напряг. G>>Прощелкиваем всю строку. Запоминаем в массив номера позиций, в которой стоят пробелы. В конце цикла пишем в массив последним элементом длину строки. Затем находим попарные разности между элементами полученного массива и записываем рядом (все можно сделать в одном цикле). К примеру, получим что-то такое:
D_S>Так было бы красивей, если бы ты заранее знал сколько элементов тебе понадобиться в таком массиве. Кроме того его еще хранить нужно где-то... Кроме того между подстроками может стоять не ожин пробел, а несколько... и т.д. и т.п.
Вот пример рабочего кода: (стековый фрейм можно было бы и не делать, +ограничение на длину строки)
format binary
org 100h
;a test values
mov cx, StrLen
mov si, strText
sub cx, si
;proc
;in:
;cx - stringLen
;si - stringPtr
;
;out:
;ax - last space position
;bx - max word length
;
;size - 44
enp:
push bp
mov bp,sp
sub sp,cx
push si ;save initial position to stack
xor bx,bx
L:
lodsb
cmp al, 32
je found ;a space found
or al,al
jnz endl
found:
pop ax ;get an old position from stack
push ax ;saving previous space position
push si ;save current space position in stack
sub ax,si
neg ax
dec ax ;ax = prev. word length
cmp ax,bx ;bx = maxLength
jna endl
xchg ax, bx ;ax > bx
xchg bp, sp
mov di, [bp+2] ;di = Last Space Position
xchg bp, sp
endl:
loop L
xchg ax,di
mov sp,bp
pop bp
ret
strText db'This is a sente111111111111111111nce for testing purposes.',0
StrLen db 0