Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.02.25;
Скачать: [xml.tar.bz2];

Вниз

Функция, убирающая пробелы в строке   Найти похожие ветки 

 
Ученик2   (2004-02-11 17:58) [0]

никто не подскажет, есть ли такая функция?
а то самому писать не очень хочется


 
MBo   (2004-02-11 17:59) [1]

>а то самому писать не очень хочется
а придется


 
Юрий Федоров   (2004-02-11 17:59) [2]

StringReplace


 
TUser   (2004-02-11 18:06) [3]

function DeleteSpaces(s:string):string;
begin
while pos(" ",s) do
delete(s,pos(" ",s),1);
result:=s;
end;
Ctrl-C->Ctrl-V


 
Ученик2   (2004-02-11 18:13) [4]

to TUser
у Юрия Федотова прикольнее


 
Amoeba   (2004-02-11 18:27) [5]

Скачай библиотеку QStrings
function Q_DeleteText(var S: string; const SubStrToDel: string): Integer;

{ Q_DeleteText удаляет из строки S все вхождения подстроки SubStrToDel. Поиск
подстроки ведется без учета регистра символов. Функция возвращает количество
найденных (и удаленных) фрагментов. }

procedure Q_ReplaceCharsByOneChar(var S: string; const ChOldSet: TCharSet;
ChNew: Char);


 
VID   (2004-02-11 18:29) [6]

Бысрее, потому что не дёргает POS постоянно
function DeleteSpaces2(s:string):string;
Var I,L:Integer;
begin
Result := "";
L:=Length(S);
IF L = 0 then exit;
For i := L downto 1 do
IF S[i] = " " then
Delete(S, I, 1);
result:=s;
end;
Ctrl-C->Ctrl-V


 
Владислав   (2004-02-11 18:30) [7]

> TUser © (11.02.04 18:06) [3]

Не завидую тому, кто использует pos на современных процах в реализации D6 и ниже (как на счет выше, не знаю). Конечно, если разговор не о строках размером в пару килобайт и меньше.

Гораздо быстрее работает сканирование от конца строки с Move. При чем алгоритм - проще, наверное, не бывает.

Вот пример:

procedure RemoveChars(var AStr: string);
var
LOriginLen: Integer;
LLen: Integer;
LCurChar: PChar;
LRemoveChars: PChar;
LSource: PChar;
LNextSource: PChar;
LDest: PChar;
LCount: Integer;
LFound: Boolean;
begin
LOriginLen := Length(AStr);
if LOriginLen = 0 then
Exit;
LLen := (LOriginLen shl 1) + Length(CRLF);
SetLength(AStr, LLen);
LCurChar := Pointer(AStr);
LSource := LCurChar;
LDest := LCurChar;
Inc(LDest, LOriginLen);
LDest^ := CR;
Inc(LDest);
LDest^ := LF;
Inc(LDest);
LFound := False;
while LCurChar <= (PChar(Pointer(AStr)) + LOriginLen) do
begin
if LCurChar^ in [ #$21..#$2F] then
begin
LFound := True;
LRemoveChars := LCurChar;
while LCurChar^ in [ #$21..#$2F] do
Inc(LCurChar);
LNextSource := LCurChar;
LCount := LRemoveChars - LSource;
if LCount = 0 then
begin
LSource := LNextSource
end
else
begin
Move(LSource^, LDest^, LCount);
LSource := LNextSource;
Inc(LDest, LCount)
end
end;
Inc(LCurChar)
end;
LCount := (PChar(Pointer(AStr)) + LOriginLen) - LSource;
if LCount > 0 then
begin
Move(LSource^, LDest^, LCount);
Inc(LDest, LCount)
end;
LLen := LOriginLen;
if LFound then
LLen := LDest - PChar(Pointer(AStr));
SetLength(AStr, LLen)
end;


Процедура удаляет из строки символы в диапазоне [ #$21..#$2F]


 
Sandman25   (2004-02-11 18:32) [8]

SetLength(Result, Length(S));
J := 0;
for I := 1 to Length(S) do
begin
if S[I] <> " " then
begin
inc(J);
Result[J] := S[I];
end;
SetLength(Result, J);


 
Владислав   (2004-02-11 18:36) [9]

> VID © (11.02.04 18:29) [6]

Ну его нафиг этот Delete.

> Amoeba © (11.02.04 18:27) [5]

QStrings надо юзать с умом. Некоторые функции от туда работают с некоторыми ограничениями. Они в большинстве случаев срабатывают (предположения), но в частных случаях могут не работать. Хотя библиотека очень быстро работает.


 
Владислав   (2004-02-11 18:38) [10]

> Sandman25 © (11.02.04 18:32) [8]

То же не фигово. Только памяти в два раза больше занимает.


 
Sandman25   (2004-02-11 18:39) [11]

[10] Владислав © (11.02.04 18:38)

Не обязательно. Если у параметра счетчик ссылок был больше 1, то все равно при изменении придется заводить новую строку.


 
Digitman   (2004-02-11 18:45) [12]


> Ученик2 (11.02.04 17:58)


лишние ? т.е терминирующие + лидирующие + более чем один между "словами" ? или в принципе - "долой пробелы !" ?


 
Владислав   (2004-02-11 18:46) [13]

> Sandman25 © (11.02.04 18:39) [11]

SetLength(Result, Length(S));

Это говорит об обязательности.


 
Владислав   (2004-02-11 18:48) [14]

> Digitman © (11.02.04 18:45) [12]

В точку вопрос ;)


 
Тимохов   (2004-02-11 18:48) [15]

может ему trim нежен?


 
Sandman25   (2004-02-11 18:49) [16]

[13] Владислав © (11.02.04 18:46)

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


 
Тимохов   (2004-02-11 18:52) [17]


> Я имел ввиду, что при изменении/удалении одного символа
> в параметре произойдет полное копирование всей строки. И
> в таком случае мой алгоритм требует столько же памяти, сколько
> и другие.

ИМОХ вы не правы.
Если это делать через move, то копирование не будет.


 
Владислав   (2004-02-11 18:52) [18]

> Sandman25 © (11.02.04 18:49) [16]

Не все. Глянь [7]. Там такого нет.


 
Sandman25   (2004-02-11 18:54) [19]

[17] Тимохов © (11.02.04 18:52)

Согласен. Но в принципе, неважно, как делать.
Была строка "qwer tyu", на которую указывали 2 переменные.
После удаления пробела получаем 2 строки:
"qwer tyu" и "qwertyu". Памяти требуется почти столько же, как в моем алгоритме.


 
Sandman25   (2004-02-11 18:55) [20]

[18] Владислав © (11.02.04 18:52)

См. [19]. Почти все. Если, конечно, у нас в строке не 50% пробелов :)


 
Владислав   (2004-02-11 19:11) [21]

> Sandman25 © (11.02.04 18:55) [20]

Ошибаешься, однако :)


 
Тимохов   (2004-02-11 19:14) [22]

Владислав.

Вот я над вами посмеюсь когда НЭТ придет - как же, поюзаешь там move :))))))) Метод классный - я его даже себе взял, на память. Но ведь переделывать имхо придется все.


 
Владислав   (2004-02-11 19:22) [23]

> Тимохов © (11.02.04 19:14) [22]

Смейтесь... Придет, буду плакать. За то сейчас мои пользователи улыбаются. Раньше на все тратилось в два раза больше времени, а сейчас я его съекономил. Там еще много всяких "штучек" используется. Вот пример:

...
asm
MOV EAX, LMessage
MOV EDX, LMessageLen
MOV ECX, [EAX - $04]
MOV LMessageLen, ECX
MOV [EAX - $04], EDX
end;
try
LCheckResult := RESULT_NOT_SPAM;
if Length(LMessage) > 0 then
LCheckResult :=
CheckMessage(TUserInfo(ASender.Thread.Data),
Pointer(LMessage), TUserInfo(ASender.Thread.Data).Adjust);
finally
asm
MOV EAX, LMessage
MOV EDX, LMessageLen
MOV ECX, [EAX - $04]
MOV LMessageLen, ECX
MOV [EAX - $04], EDX
end;
end;
...


Вот это код код съекономил мне 20% времени на исполнение.


 
Тимохов   (2004-02-11 19:31) [24]


> Владислав © (11.02.04 19:22) [23]

Да я ничего такого ругательного не говорю.
Сам люблю пооптимизировать.


 
Владислав   (2004-02-11 19:35) [25]

> Тимохов © (11.02.04 19:31) [24]

Дык и ни кто не возмущается ;)


 
Sandman25   (2004-02-12 10:39) [26]

[21] Владислав © (11.02.04 19:11)

Возможно, я и ошибаюсь. Сейчас вот сижу, изучаю Ваш алгоритм.
Дошел до строчек
LLen := (LOriginLen shl 1) + Length(CRLF);
SetLength(AStr, LLen);
и теперь я считаю, что в моем алгоритме всегда используется меньше памяти, чем в Вашем :)
В моем добавляется Length(Str) байт, в Вашем - Length(Str)+Length(CRLF).


 
Владислав   (2004-02-12 12:00) [27]

> Sandman25 © (12.02.04 10:39) [26]

Упс... Вот это я ступил. Собственно ручно неделю назад переписал эту процедурку :)

Дело в том, что в первоначальном варианте строка не дублировалась, а из нее действительно вырезались символы в диапазоне. Потом понадобилось иметь и оригинал строки и обработанную строку. Во как :) Виноват.

Изначально алгоритм был такой. Бежим по строке от конца и ищем вхождение символов в диапазоне. Если есть последовательные символы в этом диапазоне, считаем их количество. Потом строку (часть строки), которая была до этих символов сдвигаем влево на количество символов (те, что в ненужном диапазоне). Длину строки уменьшаем на количество символов (не SetLength, а просто уменьшаем значение переменной). И так до начала строки. В самый последний момент делаем SetLength. К сожалению реализации у меня не сохранилось, так что все голословно.


 
Sandman25   (2004-02-12 12:15) [28]

[27] Владислав © (12.02.04 12:00)

Может, это нескромно звучит, но мне такой алгоритм тоже приходил в голову. Но мне тогда не понравилось, что один и тот же символ может перемещаться несколько раз (сколько пробелов слева от него, столько и раз), и что при удалении первых (с начала строки) символов будет перемещаться почти вся строка. Для наихудшего случая
"1 2 3 4 5 6 7 8 9 10" будет 9 перемещений, сначала 1 символа, потом 2, потом 3 и так далее до 9.


 
Владислав   (2004-02-12 12:20) [29]

А в итоге получим те же Move. Просто добавяться лишние вызовы процедур, смысла в которых немного.

А так не будет перераспределения памяти. Ну короче, быстрее работает. :)


 
Sandman25   (2004-02-12 12:25) [30]

[29] Владислав © (12.02.04 12:20)

Ну, перераспределения памяти нет и в моем алгоритме.
ИМХО s[J] := s[I] выполняется гораздо быстрее, чем Move.
Но если перемещаться будут блоки (как оно обычно и бывает - пробелы ставят только между словами), то действительно, Ваш алгоритм может быть быстрее.
Вроде все ясно, спасибо за обсуждение :)


 
Владислав   (2004-02-12 12:31) [31]

Да не за что :)
Мне тоже познавательно :)


 
Johnmen   (2004-02-12 13:02) [32]

>Уважаемые оптимизаторы

Всё уже заоптимизировано !
http://delphibase.endimus.com/?action=viewfunc&topic=strchange&id=10395
По вопросам оптимизации обращайтесь к Sha ©


 
Владислав   (2004-01-23 13:41) [33]

Как раз оптимизаторам предложенное и не подходит :)
Но все равно спасибо.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.02.25;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.035 c
1-79988
AGN
2004-02-13 09:52
2004.02.25
Ctrl+F


4-80368
emergenter
2003-12-16 21:32
2004.02.25
API: LocalAlloc


1-79991
Galin
2004-02-13 14:04
2004.02.25
Как объявить константу в классе, чтобы использ при объяв массива?


7-80305
Borys
2003-12-04 19:54
2004.02.25
HTML


14-80269
SergP
2004-02-04 12:35
2004.02.25
Помогите с переменными в ПХП.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский