:: Visual Foxpro, Foxpro for DOS
Удаление лишних пробелов
Jlutko
Автор

Сообщений: 161
Откуда: Пермская область
Дата регистрации: 27.09.2005
Всем доброго времени суток.
Суть вопроса:
Есть строка. Между словами в строке может быть более 1 пробела, что не преемлемо (от пользователей привет, объяснять бесполезно).
Требуется удалить лишние пробелы кроме одного.
На ум приходит только перебор по символам до конца строки и выявление двойных пробелов путем сравнения текущего символа с предыдущим.
Кода пока нет. Только идея в голове вертится...
Может кто-нибудь решал нечто подобное. Посимвольный перебор кажется громозким.



Исправлено 2 раз(а). Последнее : Jlutko, 12.01.18 17:08
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
Taran

Сообщений: 13623
Откуда: Красноярск
Дата регистрации: 16.01.2008
do while space(2) $ myText
myText = strtr(myText,space(2), space(1))
enddo


P.s. проверить надо. За синтаксис. Давно не писал.



Исправлено 1 раз(а). Последнее : Taran, 12.01.18 17:13
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
Jlutko
Автор

Сообщений: 161
Откуда: Пермская область
Дата регистрации: 27.09.2005
Спасибо. Идея понятна (собственно идея и требовалась. С синтаксисом разберемся позже).
Но если больше 2-х пробелов? С юзерами может встретится все, что угодно...
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
ssa

Сообщений: 12999
Откуда: Москва
Дата регистрации: 23.03.2005
Jlutko
Спасибо. Идея понятна (собственно идея и требовалась. С синтаксисом разберемся позже).
Но если больше 2-х пробелов? С юзерами может встретится все, что угодно...
А цикл, конечно же, просто от балды поставлен? Это во-первых.
А во-вторых, поищи тут по слову Reduce.


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
Jlutko
Автор

Сообщений: 161
Откуда: Пермская область
Дата регистрации: 27.09.2005
Да, верно, туплю...
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
spinz

Сообщений: 5263
Дата регистрации: 21.01.2016
а не быстрей будет, что-то типа (сори за смесь фокспрошного синтаксиса с сишным, я просто фокспро совсем не помню)?

for(i=2;i<strlen(myText);i++)
{
if !space(i) $ myText break;
myText = strtr(myText,space(i), space(1));
}
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
Jlutko
Автор

Сообщений: 161
Откуда: Пермская область
Дата регистрации: 27.09.2005
ДА! Все работает!Все корректно!
Проверил на реальной базе. Вышло несколько проходов по строке, но, думаю, это все равно лучше, чем посимвольное сравнение.
Спасибо!
Странно, но функцию "strtr" я не знал... Дитя MS-DOS!
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
Jlutko
Автор

Сообщений: 161
Откуда: Пермская область
Дата регистрации: 27.09.2005
Я в Си не силен. Каюсь. Делфи, фокспро, VBasic - это пожалуйста...
Но, судя по моему подозрению, Вы пытаетесь устроить перебор строки по символам (может я не прав. я еще раз повторю, что в Си я не спец).
Но если так, то это то, от чего я хочу уйти.
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
Jlutko
Автор

Сообщений: 161
Откуда: Пермская область
Дата регистрации: 27.09.2005
Извиняюсь.
Более внимательно прочитал код...
Но как Ваш код может быть воспроизведен на фокспро? Остальное не преемлемо! Я просто пишу доп. функцию к бухгалтерской программе... И на чем ее писать - не мне решать!
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
Taran

Сообщений: 13623
Откуда: Красноярск
Дата регистрации: 16.01.2008
На фокс переложить не проблема.
Строчек будет поболее чем у меня.
По скорости наверно тоже минус.
У меня проверка при входе в цикл.
У spinza внутри цикла.
Если и будет разница, то семечки.
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
spinz

Сообщений: 5263
Дата регистрации: 21.01.2016
Хм, кстати, мой код некорректный.
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Быстрее будет подключить foxtools и использовать её функцию reduce. Но это всё же внешняя библиотека, таскать с собой ещё и fll придётся - это минус.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
spinz

Сообщений: 5263
Дата регистрации: 21.01.2016
Все же при реализации на "быстрых" ЯП, типа Си/ассемблера, посимвольный анализ строки кажется самым оптимальным в общем случае. Да, думаю, для длинных мегабайтных строк с длинными последовательностями пробелов и при реализации на фокспро это тоже будет оптимальным вариантом.
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
leonid

Сообщений: 3202
Откуда: Рига
Дата регистрации: 03.02.2006
Вот так будет быстрей всего

?reduce(" asdf adadasda sdfsdf fsdfsdfsfsf asdads aadasdasd ", " ")
function Reduce
lparameter m.st, m.ch
if len(m.ch)<1
return m.st
endif
if len(m.ch)>1
m.ch=left(m.ch,1)
endif
if !pemstatus(_screen,"reduce_ptr",5)
Declare Integer GetProcessHeap in Win32API
Declare Integer HeapAlloc in Win32Api Integer, Integer, Integer
Declare RtlMoveMemory in Win32API Integer, String, Integer
local m.hhnd, m.ptr, m.st2
m.st2= ;
chr(85)+chr(139)+chr(236)+chr(87)+chr(86)+chr(80)+ ;
chr(83)+chr(81)+chr(82)+chr(139)+chr(117)+chr(8)+ ;
chr(139)+chr(69)+chr(12)+chr(139)+chr(125)+chr(16)+ ;
chr(139)+chr(93)+chr(20)+chr(139)+chr(11)+chr(51)+ ;
chr(219)+chr(58)+chr(6)+chr(116)+chr(14)+chr(50)+ ;
chr(228)+chr(255)+chr(54)+chr(143)+chr(7)+chr(70)+ ;
chr(71)+chr(67)+chr(73)+chr(117)+chr(240)+chr(235)+ ;
chr(13)+chr(128)+chr(252)+chr(1)+chr(116)+chr(4)+ ;
chr(254)+chr(196)+chr(235)+chr(235)+chr(70)+chr(73)+ ;
chr(117)+chr(225)+chr(139)+chr(77)+chr(20)+chr(137)+ ;
chr(25)+chr(90)+chr(89)+chr(91)+chr(88)+chr(94)+ ;
chr(95)+chr(139)+chr(229)+chr(93)+chr(194)+chr(16)+ ;
chr(0)
m.hhnd=GetProcessHeap()
m.ptr=HeapAlloc(m.hhnd,0,len(m.st2)+16)
RtlMoveMemory(m.ptr,m.st2,len(m.st2))
_screen.addproperty("reduce_ptr",m.ptr)
endif
local m.st3,m.ln
m.st3=replicate(chr(0),len(m.st)+4)
m.ln=len(m.st)
Declare CallWindowProc in Win32API Integer, String, Integer, String @, Integer @
CallWindowProc(_screen.reduce_ptr, m.st+" ", asc(m.ch), @m.st3, @m.ln)
return left(m.st3,m.ln)
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
spinz

Сообщений: 5263
Дата регистрации: 21.01.2016
2leonid

Большая просьба в таких случаях выкладывать попутно ассемблерный код.

Ну долго же переводить маш.коды в мнемонику.
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
leonid

Сообщений: 3202
Откуда: Рига
Дата регистрации: 03.02.2006
spinz
Большая просьба в таких случаях выкладывать попутно ассемблерный код.

Его же еще искать надо.

use32
push ebp
mov ebp, esp
push edi
push esi
push eax
push ebx
push ecx
push edx
mov esi, [ebp+08h]
mov eax, [ebp+0Ch]
mov edi, [ebp+10h]
mov ebx, [ebp+14h]
mov ecx, [ebx]
xor ebx, ebx
m2:
cmp al, [esi]
je m1
xor ah, ah
m5:
push dword [esi]
pop dword [edi]
inc esi
inc edi
inc ebx
dec ecx
jne m2
jmp m3
m1:
cmp ah, 01
je m4
inc ah
jmp m5
m4:
inc esi
dec ecx
jne m2
m3:
mov ecx, [ebp+14h]
mov [ecx], ebx
pop edx
pop ecx
pop ebx
pop eax
pop esi
pop edi
mov esp, ebp
pop ebp
ret 0010h
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
spinz

Сообщений: 5263
Дата регистрации: 21.01.2016
Я бы все же сделал реализацию на "строковых" инструкциях х86 (SCASB, MOVSB), это должно
работать быстрей.



Исправлено 2 раз(а). Последнее : spinz, 12.01.18 23:27
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Полагаю, что конкретно так усилив "логику" подобного кода, можно получить очень заметное ускорение. ХитрО манипулировать DWORD-ами а не байтами (a-la "быстрые" сишные реализации memcpy), читать/писать память "по границе слова", "схлопывать" существующую строку (а не копировать ещё раз "в новую" - хотя фокс всё одно при вызове dll для "ссылочной строки" будет дважды копировать содержимое)... Используя FoxAPI или влазя во внутренности рантайма можно, вероятно, избежать и начальных "копирований" и копирований внутри LEFT-а, который, я так думаю, без выделения нового блока памяти и копирования символов не обходится (но как тогда избежать утечки памяти - тот ещё вопрос)...

Естественно это всё имеет чисто спортивный интерес, т.к. для типичных применений - "облагородить" ввод юзером весьма коротких строк-наименований - даже жутко неэффективный "цикл замены двух пробелов на один до достижения результата" вполне себе подойдёт


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
spinz
Я бы все же сделал реализацию на "строковых" инструкциях х86 (SCASB, MOVSB), это должно работать быстрей.
Вряд ли заметно быстрее (на современном железе, конечно, впрочем VFP на старых добрых 80286 и не работает ). Основной тормоз IMHO будет в чтении/записи памяти - побайтно, да без "выравнивания" это делать крайне невыгодно...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Удаление лишних пробелов
leonid

Сообщений: 3202
Откуда: Рига
Дата регистрации: 03.02.2006
spinz
Я бы все же сделал реализацию на "строковых" инструкциях х86 (SCASB, MOVSB), это должно
работать быстрей.

Так кто ж мешает то? Заодно бы и сравнили. Может как раз все наоборот.
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 22 leonid  (Гостей: 21)

© 2000-2024 Fox Club 
Яндекс.Метрика