На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
Страницы: (3) 1 2 [3]  все  ( Перейти к последнему сообщению )  
> Удалить буквы из строки до и после символа
    Цитата Fr0sT @
    PosEx и Copy(кусок до)+Copy(замена) решают задачу намного проще.
    Допускаю. Однако моей целью было - сделать код как можно быстрее (автор темы жаловался на медленную скорость); и я почти убеждён, что мой алгоритм - самый быстрый! :yes: :blush:
      А я почти убежден, что код, мягко говоря, гуано. Лень разбираться в обфусцированных идентификаторах, но уже одно вот это (s - исходная строка, s2 - искомая)
      ExpandedWrap disabled
         while Ord(s[t])<>0 do
                s2[t] := s[t];

      наводит на оч-чень сильные подозрения
        Так это ж происходит исключительно оттого, что нельзя было портить исходную строку, дабы тест провести миллион раз!
        А так-то, в итоговой, конечно этого не будет! :whistle:
          Цитата
          Ну что сказать вам, москвичи, на прощанье...
          Доделал всё и замеры уточнил, и вот что получил:
          ExpandedWrap disabled
            procedure SubStrErase( s,sub:string);
            var t,c,lenSub:integer;
            begin;
                lenSub := length(sub);
                t := 1;
                while Ord(s[t])<>0 do
                begin
                    if s[t]=sub[1] then // начало совпадения слова!?
                    begin
                        c := 0;
                        repeat inc(c); until (s[t+c]<>sub[1+c]); // считаем длину совпадения
                        if c=lenSub then
                        begin
                            repeat dec(c); until (c=0); // ставим символ удаления
                            t := t + lenSub; // много совпало - пропустим много
                        end else inc(t); // со следующего будет проверка
                    end else inc(t); // со следующего будет проверка
                end;
                // удаляем ненужные символы
                t := 1;
                repeat inc(t); until ((Ord(s[t])=0) or (s[t]='*'));
                // нашли первую '*'
                if Ord(s[t])<>0 then
                begin
                    c := t;
                    repeat inc(c); until ((Ord(s[c])=0) or (s[c]<>'*'));
                    if Ord(s[c])<>0 then
                    begin
                        repeat
                        if s[c]<>'*' then
                        begin
                            s[t] := s[c];
                            Inc(t);
                        end;
                        Inc(c);
                        until (Ord(s[c])=0);
                        s[t] := Chr(0);
                    end;
                end;
            end;
            ...
                str := 'Мама мыла раму с Тамарой. Рама сияла амальгамой';
                s2 := str;
                t2 := 0;
                for pos:=0 to 10000 do
                begin
                asm
                    rdtsc
                    mov t1, eax
                end;
                FileName := StringReplace( str, 'ама', '', [rfReplaceAll]);
                asm
                    rdtsc
                    sub eax, t1
                    mov t1, eax
                end;
                t2 := t2 + t1;
                str := s2;
                end;
                WriteLn(t2);
                t2 := 0;
                for pos:=0 to 10000 do
                begin
                asm
                    rdtsc
                    mov t1, eax
                end;
                SubStrErase( str, 'ама');
                asm
                    rdtsc
                    sub eax, t1
                    mov t1, eax
                end;
                t2 := t2 + t1;
                str := s2;
                end;
                WriteLn(t2);
          В результате имеем: 91724617 и 32633585. Ну и другие подобные варианты с итогом выигрыша в 3 раза!! ;)
          :good:
            Цитата Славян @
            В результате имеем: 91724617 и 32633585.

            Вначале я хочу сказать что ты молодец - потратил время, написал код, с нами поделился.

            Немного критики:
            У меня твой код работает так(5 запусков):
            ExpandedWrap disabled
              13.044.908 - 16.936.000
              6.636.660 - 8.803.730
              8.048.265 - 9.641.485
              11.583.250 - 17.566.347
              13.467.860 - 17.146.036

            Как видно разница минимальна
            1 И не забывай что у тебя код не универсален, не может быть применим для любого теста - давай до свидания :)
            2 Напиши на каком железе ты запускал и под какой delphi? Мне так кажется что сам компилятор оптимизирует код. Я под берлином запускал на 2 ядерном пне, как у тебя получилось в 3-6 раз медленнее?
              Славян
              и кстати да, твой код всегда проигрывает стринг реплейсу.

              Вот мой вариант:
              ExpandedWrap disabled
                procedure NewErase3(SIn,SSub:String);
                Var
                  I,I2, BadChar,LenSSub,LenSIn:Integer;
                begin
                  LenSSub:=Length(Ssub);
                  I:=0;
                  BadChar:=0;
                  LenSIn:=Length(SIn);
                  Repeat
                  inc(I);
                    Begin
                      if SIn[I]=SSub[1] then
                        Begin
                            for I2 := 2 to LenSSub do
                            if SIn[I+I2-1]=SSub[I2] then
                            Begin
                              if I2=LenSSub then
                                Begin
                                  Inc(I,LenSSub-1);
                                  Inc(BadChar,LenSSub);
                                End;
                 
                            End Else Begin SIn[I-BadChar]:=SIn[I];Break End;
                 
                        End Else SIn[I-BadChar]:=SIn[I];
                    End;
                  Until I>= LenSIn;
                  SetLength(SIn,LenSIn-BadChar);
                end;


              Он быстрее твоего, и без кастылей, но медленее чем стринг реплейса
              Через тиккаунт, в среднем
              ExpandedWrap disabled
                187:StringReplace
                234:SubStrErase
                203:NewErase


              Но все равно стрингреплейс быстрее почему-то
                Цитата ^D^ima @
                Но все равно стрингреплейс быстрее почему-то

                Потому что
                Цитата ^D^ima @
                Я под берлином

                В 10+ функцию серьезно допилили.
                  Fr0sT
                  Просто у меня и так все в 1 проход делается, а там за счет чего скорость?
                    У строки должны быть функции right(a) и left(a), которые оставляют правые a знаков или левые a знаков
                    В твоей задаче
                    ExpandedWrap disabled
                      s=s.right(5);

                    ExpandedWrap disabled
                      s=s.left(12);
                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                    0 пользователей:
                    Страницы: (3) 1 2 [3]  все


                    Рейтинг@Mail.ru
                    [ Script execution time: 0,0348 ]   [ 17 queries used ]   [ Generated: 19.04.24, 10:27 GMT ]