Chertenok.ru - все о программировании
Вход  |  Регистрация  |  Поиск 
Праздник
Через 3 дня :

День славянской письменности и культуры


Функция Explode для Делфи...


Новая тема  Ответить  Печать Предыдущая тема  Следующая тема
Автор Сообщение
Пол:Муж TuXAPuK
Великий гонщик

Предупреждений : 1
Возраст: 26
Знак зодиака: Рыбы
Зарегистрирован: 12.09.2005
Сообщения: 714
Откуда: Великий город Рига... =Ъ
СообщениеЧт, 08-Май-2008 8:20    Заголовок сообщения: Функция Explode для Делфи...
Цитата

Вот оставляю её тут на хранение, а то у меня на винтах бы затерялась...

Функция разбивки строки.

function Explode(sString, sExploader: string; out sOutArray: TStringDynArray; out iArraySize: integer): boolean;

Результат : Если строка разбивалась то вернёт true, в ином случае false.

sString : Строка которую следует разбить.
sExploader : Текст которым разбивается строка.
sOutArray : Массив строк в который будут помещаться разбитые строки.
iArraySize : Размер массива разбитых строк.

Код обновлён 10.05.2008
Pascal:
  1. uses
  2. StrUtils;
  3.  
  4. type
  5.  TStringDynArray = array of string;
  6.  
  7.  function Explode(sString, sExploader: string; out sOutArray: TStringDynArray; [color=blue]out[/color] iArraySize: integer): boolean;
  8.  var
  9.   iStrLen       : Word;
  10.   iExplLen      : Word;
  11.   sSubStr       : String;
  12.   iX            : Word;
  13.   iPos          : Word;
  14.  begin
  15.   Result := False;
  16.   // Считаем количество элементов Exploader в String
  17.   iStrLen       := Length(sString);
  18.   iExplLen      := Length(sExploader);
  19.   iArraySize    := 1;
  20.   if ( iStrLen > iExplLen) then 
  21.   begin
  22.    iPos := 0;
  23.    while ( true ) do
  24.    begin
  25.     iPos := PosEx(sExploader, sString, iPos + 1);
  26.     if (iPos <> 0) then
  27.     begin
  28.      iArraySize := iArraySize + 1;
  29.      iPos := iPos + iExplLen - 1;
  30.     end
  31.     else
  32.      break;
  33.    end;
  34.   end;
  35.   // Разбераем строку
  36.   SetLength(sOutArray, iArraySize);
  37.   if (iArraySize <> 1) then
  38.   begin
  39.    for iX := 0 to iArraySize - 1 do
  40.    begin
  41.     iPos := Pos(sExploader, sString);
  42.     if (iPos <> 0) then
  43.     begin
  44.      sOutArray[iX] := Copy(sString, 1, iPos - 1);
  45.      sString := Copy(sString, iPos + iExplLen, Length(sString) - iPos - iExplLen + 1);
  46.     end
  47.     else
  48.      sOutArray[iX] := sString;
  49.    end;
  50.    Result := True;
  51.   end
  52.    else sOutArray[0] := sString;
  53.  end;


зЫ : Хотел-бы видеть комментарии по оптимизации кода, есть идеи?

_________________


Последний раз редактировалось: TuXAPuK (Вт, 30-Ноя-2010 17:44), всего редактировалось 5 раз(а)
В начало
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
DrPass
Знающий :)
/Почетный Модератор/


Возраст: 31
Знак зодиака: Лев
Зарегистрирован: 02.05.2002
Сообщения: 5709
Откуда: Донецк
СообщениеЧт, 08-Май-2008 9:31 
Цитата

Цитата:
if ( iStrLen > iExplLen) then
for iX := 1 to (iStrLen - iExplLen) do
begin
sSubStr := Copy(sString, iX, iExplLen);
if (sSubStr = sExploader) then iArraySize := iArraySize + 1;
end;

Заменить на while c использованием PosEx и позиции поиска. Это и заметно быстрее, и избавит твою процедуру от душевных мук при обработке параметров вида sString='111111111111111111', sExploader='111'
Для оптимизации по скорости можно еще сделать два режима - цикл for если length(sExploader)=1 и while, если больше 1

_________________
Да пребудет с вами Сила!
В начало
Посмотреть профиль Отправить личное сообщение
Пол:Муж TuXAPuK
Великий гонщик

Предупреждений : 1
Возраст: 26
Знак зодиака: Рыбы
Зарегистрирован: 12.09.2005
Сообщения: 714
Откуда: Великий город Рига... =Ъ
СообщениеСб, 10-Май-2008 2:21 
Цитата

Спасибо... Как-то даже и мысли не было о такой строчке....
_________________
В начало
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Hunter
Энтузиаст




Зарегистрирован: 14.09.2006
Сообщения: 349

СообщениеСб, 10-Май-2008 12:07 
Цитата

delphi:
  1. procedure Explode(Text, Delimiter: string):TStringlist;
  2. begin
  3.   result:=TStringList.Create();
  4.   result.Text:=ReplaceString(Text, Delimiter, result.Delimiter, [rsReplaceAll]);
  5. end;


В принципе, можно было и одной строкой все реализовать.. =)

Добавлено спустя 14 минут 57 секунд:

Вот еще один алгоритм:

delphi:
  1.  
  2. function SeparateStrings(sText, sSeparator: string): array of string;
  3. var
  4.   n, l, sl: integer;
  5. begin
  6.   sl:=Length(sSeparator);
  7.   n:=Pos(sSeparator, sText);
  8.   l:=1;
  9.   while n > 0 do
  10.   begin
  11.     SetLength(result, l);
  12.     result[l-1]:=Copy(sText, 1, n-1);
  13.     sText:=Copy(sText, n+sl, maxint);
  14.     n:=Pos(sSeparator, sText);
  15.     Inc(l);
  16.   end;
  17.   SetLength(result, l);
  18.   result[l-1]:=sText;
  19. end;
  20.  


Добавлено спустя 2 минуты 39 секунд:

И еще. Это довольно специфичный вариант, но полезный для разбития строк, которые могут содержать разделитель. Например, формат CSV.

delphi:
  1.  
  2. // Парсит строку с пробелами, с учетом двойных кавычек (")
  3. // bAddEmpty - признак добавления пустых строк
  4. function ParseStr(s: String; bAddEmpty: boolean = false): TStringArray;
  5. var
  6.   i,l,rl: integer;
  7.   InBracket: boolean;
  8.   TmpStr: String;
  9.  
  10. procedure AddStr;
  11. begin
  12.   if (TmpStr='') and (not bAddEmpty) then Exit;
  13.   Inc(rl);
  14.   SetLength(result, rl);
  15.   result[rl-1]:=TmpStr;
  16.   TmpStr:='';
  17. end;
  18.  
  19. begin
  20.   i:=0;
  21.   l:=Length(s);
  22.   rl:=0;
  23.   InBracket:=false;
  24.   TmpStr:='';
  25.   SetLength(result, rl);
  26.   while i<l do
  27.   begin
  28.     Inc(i);
  29.     case s[i] of
  30.     ' ':
  31.       if not InBracket then AddStr()
  32.       else TmpStr:=TmpStr+s[i];
  33.     '"':
  34.     begin
  35.       if (i+1<l) and (s[i+1]='"') then
  36.       begin // two brackets as one bracket
  37.         TmpStr:=TmpStr+'"';
  38.         Inc(i);
  39.         continue;
  40.       end;
  41.       if InBracket then
  42.       begin
  43.         InBracket:=false;
  44.         AddStr();
  45.       end
  46.       else
  47.       begin
  48.         InBracket:=true;
  49.         continue;
  50.       end;
  51.     end;
  52.     else
  53.     // normal char
  54.     TmpStr:=TmpStr+s[i];
  55.     end;
  56.   end;
  57.   AddStr();
  58. end;
  59.  

_________________
Никому не двигаться, у меня дракон!
В начало
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Показать сообщения:   
Страница 1 из 1
Перейти:  
Новая тема  Ответить  Печать

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете присоединять файлы в этом форуме
Вы можете скачивать файлы в этом форуме
хостинг от .masterhost 
Rambler's Top100