![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Заменя пробелов [D6, Win2k]
Adam © (2003-01-27 18:13:00)Сдраствуйте мастера!
У меня следующяя проблема:
Имеется строка, в которой слова разделяются проделами. Количество пробелов между двумя словами неизвестно, оно может быть разным. Требуется это количество пробелов заменить всего одним пробелом.. Как это сделать? Помогите, пожалуйста..
danilka (2003-01-29 17:57:00) [41]так у нас тут битва за скорость?
тогда может стоит уточнить правила: убивать только лишние пробелы или пробелы и непечатные символы, использовать функции или inplace процедуры, определиться с тестированием, у меня, например, вариант Юрия Зотова (28.01.03 10:04) не совсем катит - слишком все быстро, надо текст побольше и сам цикл побольше.
Андрей Сенченко (2003-01-29 17:54:00) [42]вот измененный вариант
procedure TForm1.Button1Click(Sender: TObject);
var
s: string;
i: integer;
begin
s := "q wer t y u";
i := 1;
While s[i] > #0 do
begin
if s[i] = #32 then while s[i+1] = #32 do delete(s,i+1,1);
inc(i);
end;
ShowMessage(s);
end;
Digitman (2003-01-29 17:51:00) [43]А тема-то, однако - животрепещущая !
Наверняка DB-developer"ы здесь упражняются в "остроумии")..
Угадал ?
Mystic (2003-01-29 17:47:00) [44]Еще один вариант замены строки по месту. ;)
К преимуществам следует отнести тот факт, что поддерживается несколько пробельных и конечных символов.
var
TBL: array[Byte] of Integer;
// Инициализация массива символов, 0 - символы, 1 - разделители, 2 - терминаторы
procedure InitTBL;
var
I: Integer;
begin
for I := 0 to 255 do
TBL[I] := 0;
TBL[32] := 1;
TBL[9] := 1;
TBL[0] := 2;
end;
// Напрямую к соответсвующей функции из System.pas обратиться не удалось
procedure _LStrSetLength(var St: string; Len: Integer);
begin
SetLength(St, Len);
end;
procedure Mystic(var St: string);
asm
PUSH ESI
PUSH EDI
PUSH EAX
CALL UniqueString
POP EDX
MOV ESI, [EDX]
MOV EDI, ESI
XOR EAX, EAX
INC EAX
CLD
DEC ESI //JMP @@Loop;
@@SkipSpace:
INC ESI
@@Loop:
MOV ECX, EAX
MOVZX EAX, [ESI]
MOV EAX, [OFFSET TBL].[4*EAX]
TEST EAX, ECX
JNZ @@SkipSpace
MOVSB
CMP EAX, 1
JLE @@Loop
@@Exit:
SUB EDI, ECX
MOV EAX, EDX
DEC EDI
MOV EDX, [EAX]
SUB EDI, EDX
MOV EDX, EDI
POP EDI
POP ESI
JMP _LStrSetLength
end;
initialization
InitTBL;
Johnmen (2003-01-29 17:46:00) [45]Юрий, приведите, пожалуйста, последние результаты тестирования быстродействия предложенных алгоритмов...
Андрей Сенченко (2003-01-29 17:43:00) [46]Юрий Зотов © (29.01.03 17:28)
В одном вижу - граница цикла должна быть length(s)-1.
А второе ?
Юрий Зотов (2003-01-29 17:28:00) [47]> Андрей Сенченко © (29.01.03 17:00)
Дык... у Вас же будет гарантированный выход за пределы строки. Причем даже в двух местах.
Johnmen (2003-01-29 17:17:00) [48]>Sectey © (29.01.03 17:08)
Огласите весь список, пжалуста....
Digitman (2003-01-29 17:14:00) [49]
> Андрей Сенченко
И не обгонишь)
In-place-алгоритм при всех его видимых недостатках все же в любом случае эффективней будет из-за отсутствия необходимости итеративно перераспределять память с использованием далеко не оптимизированного для таких задач встр.менеджера памяти от Борланда
Sectey (2003-01-29 17:08:00) [50]>Андрей Сенченко ©
Твой алгоритм на 4 месте он дал - 4265
Digitman (2003-01-29 17:06:00) [51]
> mate
> этим самым ты хочешь сказать , что время выполнения задачи
> не зависит от выделяемого процессорного времени? Так?
зависит ! оч даже зависит) .. и организуя доп.код.поток ты даже меньше квантов получишь на выполнение своего кода, ежели если бы был только один осн.код.поток и в его контексте выполнялся тот же твой код.
А приоритет код.потока относителен и квантование времени, выделяемого код.потоку, расчитывается ядром относительно приоритета процесса в целом
Sectey (2003-01-29 17:04:00) [52]>mate ©
Во первых твой вариант уже предлогоался.
Во вторых ТВОЯ ФУНКЦИЯ - 23002 > Q_SpaceCompress - 688
Получается в 30 раз медленее самого быстрого
Андрей Сенченко (2003-01-29 17:02:00) [53]Ведущие и терминирующие пробелы не рассматривал.
Андрей Сенченко (2003-01-29 17:00:00) [54]Специально не вникал чужие варианты :-)) Возможно, это уже было - но я бы делал так :
procedure TForm1.Button1Click(Sender: TObject);
var
s: string;
i: integer;
begin
s := "q wer t y u";
for i := 0 to length(s) do
if s[i] = " " then
while s[i+1] = " " do delete(s,i+1,1);
ShowMessage(s);
end;
Скорее всего Digitman-a не обгоню :-)) , но интесно насколько медленнее.
mate (2003-01-29 16:52:00) [55]этим самым ты хочешь сказать , что время выполнения задачи не зависит от выделяемого процессорного времени? Так?
Digitman (2003-01-29 16:48:00) [56]
> mate
Чушь ты городишь, сударь.
Доп.код.поток никакой "шустрости" не добавляет алгоритму).. Хоть ты ему SuperHighest-приоритет дажк умудришься установить)
mate (2003-01-29 16:44:00) [57]ну для шустрости можно мой код в поток загнать и приоритет Haigest у потока.
Digitman (2003-01-29 16:36:00) [58]
> mate
На тему лаконичности исх.текста, решающего задачу - давно уже проехали, сударь)
Здесь уже бой на тему "кто шустрей")
mate (2003-01-29 16:24:00) [59]Ну ВЫ тут и написали , а надо всего лишь
while pos(" "+" ",s)<>0 do
delete(s,pos(" "+" ",s),1);
и всё ;)
а что касается " "+" " - это что бы было видно что их два
Johnmen (2003-01-29 16:09:00) [60]>Digitman © (29.01.03 16:02)
И я про то же ! Тестирование твоего варианта не совсем корректно...