for flooders
:: Главная :: Решения :: Статьи :: Сайт М. Дроздова :: Файловый архив :: Книга по VFP 9 :: Русский Help Online :: OFF-LINE Форум
   Л и с о в о д ы   в с е х   с т р а н,  о б ъ е д и н я й т е с ь !!!  

Список Форумов  :: Visual Foxpro, Foxpro for DOS
   :: Помощь сайту :: 

Удаление лишних пробелов
Jlutko
Автор

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



Исправлено: Jlutko, 12.01.18 16:08
Ratings: 0 negative/0 positive

Re: Удаление лишних пробелов
Taran

Сообщений: 7380
Откуда: Красноярск
Дата: 12.01.18 16:10:59ОтветитьЦитировать
do while space(2) $ myText  
    myText = strtr(myText,space(2), space(1))  
  enddo


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



Исправлено: Taran, 12.01.18 16:13
Ratings: 0 negative/0 positive

Re: Удаление лишних пробелов
Jlutko
Автор

Сообщений: 124
Откуда: Пермская область
Дата: 12.01.18 16:22:29ОтветитьЦитировать
Спасибо. Идея понятна (собственно идея и требовалась. С синтаксисом разберемся позже).
Но если больше 2-х пробелов? С юзерами может встретится все, что угодно...
Ratings: 0 negative/0 positive

Re: Удаление лишних пробелов
ssa
[Модератор]

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


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive

Re: Удаление лишних пробелов
Jlutko
Автор

Сообщений: 124
Откуда: Пермская область
Дата: 12.01.18 16:31:30ОтветитьЦитировать
Да, верно, туплю...
Ratings: 0 negative/0 positive

Re: Удаление лишних пробелов
spinz

Сообщений: 5063
Дата: 12.01.18 16:48:54ОтветитьЦитировать
а не быстрей будет, что-то типа (сори за смесь фокспрошного синтаксиса с сишным, я просто фокспро совсем не помню)?

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
Автор

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

Re: Удаление лишних пробелов
Jlutko
Автор

Сообщений: 124
Откуда: Пермская область
Дата: 12.01.18 17:16:30ОтветитьЦитировать
Я в Си не силен. Каюсь. Делфи, фокспро, VBasic - это пожалуйста...
Но, судя по моему подозрению, Вы пытаетесь устроить перебор строки по символам (может я не прав. я еще раз повторю, что в Си я не спец).
Но если так, то это то, от чего я хочу уйти.
Ratings: 0 negative/0 positive

Re: Удаление лишних пробелов
Jlutko
Автор

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

Re: Удаление лишних пробелов
Taran

Сообщений: 7380
Откуда: Красноярск
Дата: 12.01.18 17:36:05ОтветитьЦитировать
На фокс переложить не проблема.
Строчек будет поболее чем у меня.
По скорости наверно тоже минус.
У меня проверка при входе в цикл.
У spinza внутри цикла.
Если и будет разница, то семечки.
Ratings: 0 negative/0 positive

Re: Удаление лишних пробелов
spinz

Сообщений: 5063
Дата: 12.01.18 17:49:17ОтветитьЦитировать
Хм, кстати, мой код некорректный.
Ratings: 0 negative/0 positive

Re: Удаление лишних пробелов
Igor Korolyov

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


------------------
WBR, Igor
Ratings: 0 negative/0 positive

Re: Удаление лишних пробелов
spinz

Сообщений: 5063
Дата: 12.01.18 19:25:57ОтветитьЦитировать
Все же при реализации на "быстрых" ЯП, типа Си/ассемблера, посимвольный анализ строки кажется самым оптимальным в общем случае. Да, думаю, для длинных мегабайтных строк с длинными последовательностями пробелов и при реализации на фокспро это тоже будет оптимальным вариантом.
Ratings: 0 negative/0 positive

Re: Удаление лишних пробелов
leonid

Сообщений: 2503
Откуда: Рига
Дата: 12.01.18 20:59:36ОтветитьЦитировать
Вот так будет быстрей всего

  
    
  ?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

Сообщений: 5063
Дата: 12.01.18 21:03:00ОтветитьЦитировать
2leonid

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

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

Re: Удаление лишних пробелов
leonid

Сообщений: 2503
Откуда: Рига
Дата: 12.01.18 21:17:45ОтветитьЦитировать
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

Сообщений: 5063
Дата: 12.01.18 22:16:08ОтветитьЦитировать
Я бы все же сделал реализацию на "строковых" инструкциях х86 (SCASB, MOVSB), это должно
работать быстрей.



Исправлено: spinz, 12.01.18 22:27
Ratings: 0 negative/0 positive

Re: Удаление лишних пробелов
Igor Korolyov

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

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


------------------
WBR, Igor
Ratings: 0 negative/0 positive

Re: Удаление лишних пробелов
Igor Korolyov

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


------------------
WBR, Igor
Ratings: 0 negative/0 positive

Re: Удаление лишних пробелов
leonid

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

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



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

On-line: 46 and Guests: 46


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