Форум: "Основная";
Текущий архив: 2002.09.02;
Скачать: [xml.tar.bz2];
ВнизИзбавление от нулей в строчке??? Найти похожие ветки
← →
CCCatch (2002-08-21 12:40) [0]Как удалить все имеющиеся нули из Edit1??
← →
CCCatch (2002-08-21 12:46) [1]Причём удалить нужно только нули, а всё остальное оставить
← →
Anatoly Podgoretsky (2002-08-21 12:49) [2]Процедура Delete в цикле
← →
Alx2 (2002-08-21 12:51) [3]>Anatoly Podgoretsky © (21.08.02 12:49)
сложность порядка O(n^2) вместо O(n).
← →
Dmitriy Polskoy (2002-08-21 12:53) [4]
procedure TForm1.Button1Click(Sender: TObject);
var
S: string;
begin
S := "000123.5";
while Pos("0", S) > 0 do
delete(s,Pos("0", S),1);
ShowMessage(s);
end;
← →
Alx2 (2002-08-21 13:00) [5]>Dmitriy Polskoy © (21.08.02 12:53)
Очень медленно будет работать:(
Хотя может я и зря: нужна ли здесь скорость? :)
← →
Jeer (2002-08-21 13:01) [6]S := StringReplace(S, "0", "rfReplaceAll" );
← →
Anatoly Podgoretsky (2002-08-21 13:02) [7]Alx2 © (21.08.02 12:51)
сложность порядка O(n^2) вместо O(n).
Это почему же, я предлагаю сделать это за один проход
← →
Alx2 (2002-08-21 13:03) [8]>Anatoly Podgoretsky © (21.08.02 13:02)
Внутри Delete тоже будет все перетаскиваться за O(n). Отсюда квадратичность.
← →
McSimm (2002-08-21 13:13) [9]>Alx2 © (21.08.02 13:03)
Внутри Delete тоже будет все перетаскиваться за O(n)
не будет. Обычный move() будет.
>Jeer © (21.08.02 13:01)
чуть подправлю:
S := StringReplace(S, "0", "", [rfReplaceAll]);
← →
Alx2 (2002-08-21 13:16) [10]>McSimm © (21.08.02 13:13)
>не будет. Обычный move() будет.
Блин, а третьим параметром в move что идет?!
← →
McSimm (2002-08-21 13:32) [11]Alx2 © (21.08.02 13:16)
а третьим параметром в move что идет?!
А, в этом смысле :)
Ну, считать rep movsb за цикл это несколько жестко, хотя принципиально ты прав.
Однако, меня интересует твой алгоритм. Если в цикле
if S1[i] <> "0" then S2 := S2 + S1[i],
то IMHO это намного медленнее
← →
Alx2 (2002-08-21 13:39) [12]>McSimm © (21.08.02 13:32)
>Ну, считать rep movsb за цикл это несколько жестко, хотя
>принципиально ты прав.
Самый настоящий цикл. И не намного быстрее цикла на базе явных условных переходов, а на некоторых процессорах даже и медленнее.
← →
Alx2 (2002-08-21 13:49) [13]>McSimm © (21.08.02 13:32)
В S1 - строка без нулей.
Var S, S1 : String;
k,l : integer;
begin
S := "000sdfdss00000001000000фыаф001100fgh000010";
setLength(S1,Length(S));
l := 0;
for k := 1 to Length(S) do
if S[k]<>"0" then
begin
inc(l);
S1[l] := S[k]
end;
SetLength(S1,l);
ShowMessage(S1);
end;
← →
Alx2 (2002-08-21 14:24) [14]>McSimm © (21.08.02 13:32)
>if S1[i] <> "0" then S2 := S2 + S1[i],
>то IMHO это намного медленнее
Того же порядка: O(n^2)
← →
lak_b (2002-08-21 14:32) [15]не... ну запарили с такими вопросами... можд ещё компонент такой забацать?! вот они - программисты... ладнаб ещё спросил, какой самый быстрый способ сабжа...
← →
McSimm (2002-08-21 14:33) [16]>Alx2 ©
Согласен, твой вариант быстрее. Но, как ты уже сам подметил, это не тот случай где нужна подобная оптимизация :)
Хотя, ты наверное будешь удивлен, для некоторых ситуаций следующая функция работает быстрее :)
function A2(const S: String): String;
var i: Integer;
begin
Result := S;
for i := Length(Result) downto 1 do
if Result[i] = "0" then Delete(Result, i, 1)
end;
← →
McSimm (2002-08-21 14:41) [17]>lak_b © (21.08.02 14:32)
:) Не придирайся, ну не спросил, пусть самим интересно, какая разница ?
>Alx2 ©
например на таком тесте:
for I := 1 to 100000 do A2(IntToStr(I))
← →
Alx2 (2002-08-21 15:07) [18]>lak_b © (21.08.02 14:32)
Не мешай извращаться :)
>McSimm © (21.08.02 14:41)
При таком подходе это все-таки быстрее: :)
function a3(const S: string): string;
var k, l: integer;
begin
Result := S;
l := pos("0", Result);
if l > 0 then
begin
for k := l + 1 to Length(Result) do
if Result[k] <> "0" then
begin
Result[l] := Result[k];
inc(l);
end;
SetLength(Result, l - 1);
end;
end;
← →
McSimm (2002-08-21 15:20) [19]Соревнования !
Дуель !
:)
procedure TForm1.Button1Click(Sender: TObject);
var I: Integer;
D2, D3: TDateTime;
begin
D2 := Now;
for I := 1 to 100000 do
A2(IntToStr(I));
D2 := Now - D2;
D3 := Now;
for I := 1 to 100000 do
A3(IntToStr(I));
D3 := Now - D3;
Memo1.Lines.Add("A2 = "+FloatToStr(D2));
Memo1.Lines.Add("A3 = "+FloatToStr(D3));
Memo1.Lines.Add("A2 - A3 = "+FloatToStr(D2-D3));
if D2 < D3 then ShowMessage("АГА :)")
else ShowMessage("УГУ :(")
end;
Ага !
← →
Alx2 (2002-08-21 15:27) [20]Memo1:
A2 = 1.62037031259388E-6
A3 = 1.50463165482506E-6
A2 - A3 = 1.15738657768816E-7
УГУ :(
-------------
Ха-ха!
???
← →
Alx2 (2002-08-21 15:34) [21]Вдесятеро больший цикл:
Memo1
A2 = 1.73842563526705E-5
A3 = 1.69328704942018E-5
A2 - A3 = 4.51385858468711E-7
Снова мой алгоритм победил.
← →
McSimm (2002-08-21 16:09) [22]>Alx2 © (21.08.02 15:27)
A2 = 2,16435000766069E-6
A3 = 2,17592605622485E-6
A2 - A3 = -1,15760485641658E-8
Предлагаю ничью и завязываем с этой темой :)
>Вдесятеро больший цикл
Это уже другая ситуация:
"для некоторых ситуаций следующая функция работает быстрее"
← →
Alx2 (2002-08-21 16:14) [23]>McSimm © (21.08.02 16:09)
Ничья - нечестно :)
В предлагшаемой оценке времени есть случайные колебания. Посему время испытания должно быть достаточным, чтобы достаточно уменьшить влияние помех.
← →
Ученик (2002-08-21 16:20) [24]A2 = 1.44675868796185E-6
A3 = 1.44675868796185E-6
A2 - A3 = 0
← →
Толик (2002-08-21 16:29) [25]Не очень понятно о чём спор? Т.к. последовательность не сортированная, то кроме последовательного перебора здесь ничего не придумать. Весь вопрос сводится к тому, что "очищенные" данные надо не сдвигать, а переносить предварительно выделенное место.
← →
McSimm (2002-08-21 16:56) [26]Толик © (21.08.02 16:29)
Не очень понятно о чём спор?
На самом деле абсолютно ни о чем :)
← →
Alx2 (2002-08-21 17:02) [27]
procedure UniversalDelete(Var Arr; ArrSize : Integer; ElemSize, DeleteIdx : Integer);
Var
Source, Dest : Integer;
DummyArr : array of char absolute Arr;
Begin
ArrSize := ArrSize * ElemSize;
Source := (DeleteIdx+1)*ElemSize;
Dest := Source-ElemSize;
Move(DummyArr[Source],DummyArr[Dest],ArrSize-(DeleteIdx+1)*ElemSize);
SetLength(DummyArr,ArrSize div ElemSize - 1);
End;
Пример использования:
Var
SS : array of integer;
begin
setlength(SS,10);
for k := 0 to 9 do SS[k] := (k);
UniversalDelete(SS,Length(SS),SizeOf(SS[0]),2);
Первый параметр - массив.
Второй - количество элементов в нем
Третий - размер одного элемента массива
Четвертый - номер удаляемого элемента (считая с нуля).
PS.
Будь осторожен. Написано в черновую, хоть глюков пока не замечено (но потенциально может испортить работу менеджера памяти - надо проверить)
← →
Alx2 (2002-08-21 17:03) [28]>Alx2 © (21.08.02 17:02)
Ребята, сорри!
Веткой ошибся.
← →
Alx2 (2002-08-21 17:14) [29]>Толик © (21.08.02 16:29)
Так... пальцы размять, отдохнуть...
← →
Anatoly Podgoretsky (2002-08-21 17:33) [30]Не вижу смысла в оптимизации, речь идет об Edit.Text не те размеры, даже цикл while Pos("0", ) будет слишком быстрый
← →
Ученик (2002-08-21 17:47) [31]>CCCatch (21.08.02 12:40)
Так может просто не давать их вводить ? :)
← →
McSimm (2002-08-21 17:56) [32]>Anatoly Podgoretsky © (21.08.02 17:33)
Разумеется. Весь этот спор шутки ради.
Мы уже закончили.
← →
Alx2 (2002-08-22 08:28) [33]>Anatoly Podgoretsky © (21.08.02 17:33)
>Не вижу смысла в оптимизации, речь идет об Edit.Text не те
>размеры, даже цикл while Pos("0", ) будет слишком быстрый
Да, конечно. В этом частном случае.
Но когда, например, в UBPFD появляются "кривые" в этом плане примеры, невольно задумаешся откуда же растут ноги....
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.09.02;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.008 c