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

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

Функция, вырезающая строку между двумя разделителями


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

Piter ©   (2005-08-19 21:28:00) 

Ищу функцию, в которую передается 3 параметра: исходная строка и два разделителя.
Результатом является строка, находящяяся между этими двумя разделителями в исходной строке.

Ну хотелось бы как можно быстрее :)

прототип:

function CutString(Src, BeginSeparator, EndSeparatpr: string): string

Примеры работы:

CutString('abcdefg', 'ab', 'ef') = 'cd'

CutString('bbvatzq', 'a', 'b') = ''


Piter   (2005-08-22 16:03:00) [21]

Anatoly Podgoretsky ©   (22.08.05 15:23) [27]
Найти начало и записать его в переменную K
Если K>0 (здесь постановка отсутствует


Вероятно, имелось в виду K<1.
Если K < 1 - то результат пустая строка, кроме случая когда BeginSeparator = '', тогда K = 1

Далее если М = 0 (здесь постановка отсутствует

Если M = 0 - то результат функции - пустая строка, кроме случаев EndSeparator = '', тогда M равен последнему символу во входящей строке

Anatoly Podgoretsky ©   (22.08.05 15:23) [27]
написать за пару минут функцию.


напишите


Piter   (2005-08-22 15:56:00) [22]

afanasic   (22.08.05 15:09) [24]
Delete(St,1,k1-1);


даже тестировать не имеет смысла. Будет ОЧЕНЬ долго...


Piter   (2005-08-22 15:53:00) [23]

Leonid Troyanovsky ©   (22.08.05 14:10) [18]

сравнил :(
Твой вариант в 20 раз медленнее.

Если не возражаешь против такого теста:

procedure TForm1.Button1Click(Sender: TObject);
const
 cSizeString = 300000; // массив для тестирования будет состоять из 300 тысяч строк
var
 arr, ArrBeginSeparator, ArrEndSeparator: array of string;
 i, CountSymbol: integer;
 Time1, Time2: cardinal;

 function GenerateString(Size: integer): string;
 var
   i: integer;
 begin
   SetLength(Result, Size);
   Randomize;
   for i := 1 to Length(Result) do
     Result[i] := Chr (Random( ord('z') - ord('a') ) + ord('a') ); // символы генерятся от a до z
 end;

begin
 SetLength(arr, cSizeString);
 SetLength(ArrBeginSeparator, cSizeString);
 SetLength(ArrEndSeparator, cSizeString);
 Randomize ;
 for i := 0 to High(arr) do
   begin
     CountSymbol := Random(1000) + 5; // длина строк от 5 до 1000 символов
     arr[i] := GenerateString(CountSymbol);
     CountSymbol := Random(30) + 3; // длина разделителей от 3 до 30 символов
     ArrBeginSeparator[i] := GenerateString(CountSymbol);
     CountSymbol := Random(30) + 3; // длина разделителей от 3 до 30 символов
     ArrEndSeparator[i] := GenerateString(CountSymbol);
   end;

 Time1 := GetTickCount;
 for i := 0 to High(arr) do
   CuteStringMy(arr[i], ArrBeginSeparator[i], ArrEndSeparator[i]);
 Time1 := GetTickCount - TIme1;

 Time2 := GetTickCount;
 for i := 0 to High(arr) do
   CuteStringLVT(arr[i], ArrBeginSeparator[i], ArrEndSeparator[i]);
 Time2 := GetTickCount - TIme2;

 showmessage(IntToStr(Time1) + #13#10 + IntToStr(Time2));
end;


Готовый проект - http://piter.pechora.org/temp/test_cute_string_Piter_vs_LVT.zip

Пробовал тестировать на 1 миллионе строк - не хватило вирт. памяти :)


Anatoly Podgoretsky   (2005-08-22 15:28:00) [24]

afanasic   (22.08.05 15:19) [26]
Шило на мыло, не надо ни удалять ни копировать. Надо найти начало и конец и работать уже с этим. Операции изменения строки очень медленные. Это выделение памяти (возможно освобождение старой), копирование информации. А в конце концов окажется, что от исходной строки в пару сотен килобай нужно только один/два символа. Автор заостряет вопрос как сделать это оптимально, а не как вообще сделать.


Anatoly Podgoretsky   (2005-08-22 15:23:00) [25]

Алгоритм долже быть примерно таким
Найти начало и записать его в переменную K
Если K>0 (здесь постановка отсутствует) тогда или выход или установка К=1

Далее если М = 0 (здесь постановка отсутствует), или выход или установка М=конец строкитогда концом считать последнюю позицию или выход из фукнции, поскольку условие не выполнилось, оставим это автору.

Если K и M равно 0 (постановка отсутствует) то выход или копирование с установкой других значений.

Кроме этого ответить на вопросы от других участников, какой должен быть вариант и уточнив постановку написать за пару минут функцию.


afanasic   (2005-08-22 15:19:00) [26]

Вместо Delete(...)
St := Copy(St,k1,Length(st)-k1+1);


Anatoly Podgoretsky   (2005-08-22 15:15:00) [27]

afanasic   (22.08.05 15:09) [24]
Надо избежать использования Delete это очень медленная операция.


afanasic   (2005-08-22 15:09:00) [28]

Тогда, учитывая и такую подставу:
 CutString('abcd','abc','bcd'), очень просто и достаточно быстро, причем вместо Pos можно использовать любую функцию, которая быстрее:

function CutString(St, BegSt, EndSt: String): String;
var
 k1,k2,n: Integer;
begin
 Result := '';
 // поищем первую строку
 k1 := Pos(BegSt,St);
 // если есть, то будем искать вторую после первой
 if k1 > 0 then
   begin
     Delete(St,1,k1-1);
     k2 := Pos(EndSt,St);
     if k2 > 0 then
       begin
         n := Length(BegSt);
         Result := Copy(st,n+1,k2-n-1);
       end;
   end;
end;


Alx2   (2005-08-22 15:09:00) [29]

>Piter ©   (19.08.05 21:28)  

Как велика (в среднем) строчка-аргумент?


Anatoly Podgoretsky   (2005-08-22 15:04:00) [30]

Piter ©   (22.08.05 14:51) [21]
В 11 был задан совсем другой вопрос, соображения по "сабжу", а не "как написать функцию". Правильно формулировать вопросы это твоя задача. Предъявлять по этому поводу предензии по крайней мере некрасиво.


Piter   (2005-08-22 14:51:00) [31]

Anatoly Podgoretsky ©   (22.08.05 13:39) [17]
если соображения не нужны то зачем же спрашиваешь


а-а-а... ясно. То есть, на вопрос "Как написать функцию..." ответ "Можно написать" и является соображением? :)
Ок, ок, я не понял :)))

afanasic   (22.08.05 14:26) [19]
А что мы будем делать в таком варианте:
 CutString('cbcabdaca','b','a') = ???


= 'c'


afanasic   (2005-08-22 14:27:00) [32]

Ибо алгоритмы будут существенно различаться...


afanasic   (2005-08-22 14:26:00) [33]

А что мы будем делать в таком варианте:
  CutString('cbcabdaca','b','a') = ???
Какое значние правильное:
  'c',
  'cabd' или
  'cabdac'?


Leonid Troyanovsky   (2005-08-22 14:10:00) [34]


> Piter ©   (22.08.05 13:25) [16]
> Я же не спрашивал - можно ли написать такую функцию.
> Я просил наиболее оптимальный вариант.
>
> Хотя бы оптимальнее моего в [8]


Вот тебе еще вариант (сделан на коленке).
Теперь можешь и сравнивать.


function CutString(const Src, BeginSeparator, EndSeparator: string): string;
var
 p, p1, p2, pe : PChar;
begin
  p := PChar(src);
  p1 := nil;
  p2 := nil;
  pe := p + Length(Src);

  while (p <= pe) and not Assigned(p2) do
    begin
       if StrLComp(p, PChar(BeginSeparator), Length(BeginSeparator)) = 0 then
         begin
           p1 := p + Length(BeginSeparator);
           p := p1;
           while p <= pe do
             begin
               if StrLComp(p, PChar(EndSeparator), Length(EndSeparator)) = 0 then
                 begin
                   p2 := p;
                   Break;
                 end
               else
                 inc(p);
             end;
         end
       else
         inc(p);
    end;

  if Assigned(p2) then
    SetString(Result, p1, p2-p1);
end;


--
Regards, LVT.


Anatoly Podgoretsky   (2005-08-22 13:39:00) [35]

Piter ©   (22.08.05 13:24) [15]
Не к теме ветки, а в первую очередь к сообщению номер 11, если соображения не нужны то зачем же спрашиваешь, по крайней мере предупреждай, что вопрос риторический.


Piter   (2005-08-22 13:25:00) [36]

Я же не спрашивал - можно ли написать такую функцию.
Я просил наиболее оптимальный вариант.

Хотя бы оптимальнее моего в [8]


Piter   (2005-08-22 13:24:00) [37]

Функцию? Это понятно, что ее можно написать, а что дальше?

Можно ОС написать. И программу управления ядерными ракетами - тоже можно написать.

Не понимаю - как это относится к теме ветке?


Defunct   (2005-08-22 03:57:00) [38]

> кого написать?

Миша ты же не тормоз?
Его - т.е. сабж.


Piter   (2005-08-22 03:53:00) [39]

Anatoly Podgoretsky ©   (20.08.05 12:50) [12]

кого написать?


Anatoly Podgoretsky   (2005-08-20 12:50:00) [40]

Есть соображение, что его можно написать.


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

Наверх

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