Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Заменя пробелов [D6, Win2k]


Страницы:   1 2 3 4 5 6

Adam ©   (2003-01-27 18:13:00) 

Сдраствуйте мастера!

У меня следующяя проблема:

Имеется строка, в которой слова разделяются проделами. Количество пробелов между двумя словами неизвестно, оно может быть разным. Требуется это количество пробелов заменить всего одним пробелом.. Как это сделать? Помогите, пожалуйста..


Digitman   (2003-01-29 16:02:00) [61]

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


Johnmen   (2003-01-29 15:57:00) [62]

>Digitman © (29.01.03 14:51)
>> Johnmen
>Чего то я тебя не понял)

Да, не понял ! Имелась в виду процедура тестирования от Юрий Зотов ©.



Digitman   (2003-01-29 14:51:00) [63]


> Johnmen


Чего то я тебя не понял)

> После первого же вызова .. строка Srс уже не та,
> что раньше: все слова в Src разделены одним пробелом.


Разумеется ! На то и in-place-алгоритм...
Убирает лишние (ведущие/терминирующие/межсловные) пробелы в указанном блоке памяти со строковыми данными, терминированными #0


> Все последующие итерации цикла просто ничего не делают.


Какие итерации-то ? Вызов уже сделан, Result указывает на тот же блок данных (либо nil, если Src-строка пуста)


Johnmen   (2003-01-29 14:36:00) [64]

> Юрий Зотов © (29.01.03 14:08)
> Оно входило в общее время.

А нет ли здесь ошибки ? После первого же вызова Digitman() строка Scr уже не та, что раньше: все слова в Src разделены одним пробелом. Все последующие итерации цикла просто ничего не делают.


Юрий Зотов   (2003-01-29 14:08:00) [65]

> Johnmen © (29.01.03 10:38)
> как учитывалось время на преобразование string<->pchar в
> варианте Digitman?

Оно входило в общее время. Вызов был таким:
S := String(Digitman(PChar(Src)));

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

Как Вы понимаете, я и не ставил задачей сделать хороший тест. Это всего лишь оценка на скорую руку. Но даже такие и оценочные результаты дают неплохой материал для выводов, не так ли?


REA   (2003-01-29 10:58:00) [66]

Может борду открыть "Нет пробелам"? Или "Состязания по переходу с Delphi на Assembler". В принципе можно просто "Загадочки". Победителям давать малиновые штаны.


Johnmen   (2003-01-29 10:38:00) [67]

>Юрий Зотов ©

Q_SpaceCompress не может участвовать в соревновании, т.к. соревнуются коды, написанные на D.

Юрий, как учитывалось время на преобразование string<->pchar в варианте Digitman © ?


MBo   (2003-01-29 10:13:00) [68]

>Абсолютный рекорд?
Ну так и должно быть - QStrings - хорошо отлаженная и оптимизированная библиотека, обогнать ее довольно сложно, обычно только на специальных, а не на общих задачах.
Кстати, один из ее авторов - Сергей Щербаков (Mover) - входит в число авторов этого сайта.


Юрий Зотов   (2003-01-29 09:57:00) [69]

Тест Q_SpaceCompress - 9, 10, 13.
Абсолютный рекорд?


Sectey   (2003-01-29 09:46:00) [70]

>Юрий Зотов

Q_SpaceCompress - лучше.

ReduceSpaces - 891

исходный код из QStrings v6.06

Q_SpaceCompress удаляет из строки начальные и конечные пробелы и управляющие символы (меньше пробела). Кроме того, все подряд ущие пробелы и управляющие символы в середине строки заменяются одним пробелом. Исходная строка при этом не изменяется. Эта функция работает медленнее, чем Q_SpaceCompressInPlace

function Q_SpaceCompress(const S: string): string;
asm
PUSH ESI
MOV ESI,EDX
TEST EAX,EAX
JE @@qt
MOV ECX,[EAX-4]
TEST ECX,ECX
JE @@qt
PUSH EBX
MOV EBX,EAX
XOR EDX,EDX
MOV EAX,ESI
CALL System.@LStrFromPCharLen
MOV ECX,[EBX-4]
MOV EDX,[ESI]
@@lp1: CMP BYTE PTR [EBX],$20
JA @@ex1
INC EBX
DEC ECX
JNE @@lp1
JMP @@wq
@@ex1: DEC ECX
@@lp2: CMP BYTE PTR [EBX+ECX],$20
JA @@lp3
DEC ECX
JMP @@lp2
@@lp3: MOV AL,BYTE PTR [EBX]
INC EBX
CMP AL,$20
JBE @@me
@@nx: MOV BYTE PTR [EDX],AL
INC EDX
DEC ECX
JNS @@lp3
@@wq: MOV EAX,[ESI]
MOV BYTE PTR [EDX],0
SUB EDX,EAX
MOV [EAX-4],EDX
POP EBX
POP ESI
RET
@@me: MOV BYTE PTR [EDX],$20
INC EDX
DEC ECX
JS @@wq
@@ml: MOV AL,BYTE PTR [EBX]
INC EBX
CMP AL,$20
JA @@nx
DEC ECX
JNS @@ml
JMP @@wq
@@qt: MOV EAX,ESI
CALL System.@LStrClr
POP ESI
end;


Delirium^.Tremens   (2003-01-29 09:36:00) [71]

Заменя пробелов
А за меня - Забоев.
:-)


Separator   (2003-01-29 09:33:00) [72]

Кто следующий?


Юрий Зотов   (2003-01-29 09:29:00) [73]

> Digitman © (29.01.03 09:10)
> in-place-вариант удаления лишних пробелов

И его результат - 14, 14, 13.
На сегодня это рекорд. Кто хочет посостязаться?


Sectey   (2003-01-29 09:27:00) [74]

Люди ну возмите библиотеку QStrings и не надо изобретать велосипед. Там есть функции пости на все случаи жизни. Если кого интеремует намыл.

Я тут произвел небольшой тест и вот что получилось.

Q_SpaceCompress - 688
sha - 797
Romkin - 1468
Separator - 13219
Antosya - 20250
OneSpace - 29845
Song - 389937
StrDelSpace - умер

процедура теста:
procedure TForm1.Button1Click(Sender: TObject);
var
s : string;
t : DWORD;
i : integer;
begin
t := GetTickCount;
for i:= 0 to 1000000 do
begin
s := "ssd sd sd s s sds d s d sd sd s sd s ";
Separator(s);
end;

ShowMessage(s + #13#10 + IntToStr(GetTickCount - t));
end;


Digitman   (2003-01-29 09:12:00) [75]

Преимущества : нет перераспределения памяти
Недостатки : не будет работать с read-only-строкой


Digitman   (2003-01-29 09:10:00) [76]

in-place-вариант удаления лишних пробелов:


function ReduceSpaces(Src: PChar): PChar;
var
i,j,c,f: Integer;
k: Boolean;
begin
Result := Src;
if Assigned(Result) then
begin
if Result[0] <> #0 then
begin
i:= 0;
j:= 0;
c:= 0;
f:= 0;
k:= False;
while Result[i] <> #0 do
begin
if Result[i] <> " " then
begin
if not k then
begin
k:= True;
c:= 0;
Inc(f);
end;
if i > j then
Result[j]:= Result[i];
Inc(j);
end
else
begin
if k then
begin
k:= False;
if i > j then
Result[j]:= Result[i];
Inc(j);
end
else
begin
if (f > 0) and (c = 0) then
begin
if i > j then
Result[j]:= Result[i];
Inc(j);
end;
end;
Inc(c);
end;
Inc(i);
end;
if c > 0 then
Dec(j);
Result[j]:= #0;
end
else
Result := nil;
end;
end;


Separator   (2003-01-29 08:26:00) [77]


> Anatoly Podgoretsky © (29.01.03 08:08)

Сапасибо за разъяснение, теперь понял


Бук   (2003-01-29 08:10:00) [78]

> Юрий Зотов © (28.01.03 15:18)
Если Вы внимательно читали тему, то вопрос был не о скоростивыполнения алгоритма, а о том как. И я не ставил перед собой цель написать высокоскоростной алгоритм удаления пробелов. Что касается скорости - все вопросы к Борланду :))

> Что же касается "сердито"... а что это такое - "сердитый алгоритм"?

Не надо придераться к словам....
-----------------------------------
С уважением Бук


Anatoly Podgoretsky   (2003-01-29 08:08:00) [79]

Ну если не понял, что было тебе сказано, то вот упрощенным русским языком

Нет начальное инициализации возвращаемого значения. Надо в начале сделать Result := "";, Space то ты нинциализировал.


Separator   (2003-01-29 07:43:00) [80]


> Юрий Зотов © (29.01.03 01:29)

Укажите мне на ошибку, а то я её что-то не замечаю. Хоть десять раз по циклу запустить, все равно работает правильно. Все пробелы идущие последовательно и имеющие количество большее одного заменяются на один.


Страницы:   1 2 3 4 5 6

Наверх

Титульная страница Поиск, карта сайта Написать письмо