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

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

Разбиение строки в масив [D7]


Страницы:   1 2

Селезин ©   (2006-08-21 11:36:00) 

Тема, наверное, старая и известная. Спрашиваю не ради решения, а ради лучшего решения.
Имеется строка с разделителями внутри (типа 'aa1|bb2|cc3'). Нужно разить ее и загнать в массив ['aa1','bb2','cc3'] в D7. Вариантов решения, конечно, море (насколько я знаю, стандартной функции нет). А как бы это сделать с наименьшими затратами?


Пусик   (2006-08-22 11:31:00) [1]


> Селезин ©   (22.08.06 00:39) [27]
> А чем плох Copy?-----Вообще-то вопрос был - какой алгоритм
> будет работать быстрее всего и с меньшими затратами памяти?
>  До сих пор нет ни одного ответа на ЭТОТ вопрос.


У тебя есть несколько вариантов. Тестируй, проверяй.

При желании, можешь реализовать наиболее эффективные алгоритмы:
http://alglib.sources.ru/
http://algolist.manual.ru/


guav   (2006-08-22 02:39:00) [2]

Если можно обойтись элементами выходного массива типа PChar, то сохранить где-либо строку, в цикле заменять разделители на #0 и запоминать начала подстрок.


Селезин   (2006-08-22 02:29:00) [3]

> [28] Ketmar ©   (22.08.06 00:48)
:) Спасибо..


Ketmar   (2006-08-22 00:48:00) [4]

> [27] Селезин ©   (22.08.06 00:39)
ассемблерный. оптимизированный руками под каждый процессор.


Селезин   (2006-08-22 00:39:00) [5]

А чем плох Copy?
-----
Вообще-то вопрос был - какой алгоритм будет работать быстрее всего и с меньшими затратами памяти? До сих пор нет ни одного ответа на ЭТОТ вопрос.


Gydvin   (2006-08-21 18:50:00) [6]


> тут будут возникать перераспределения памяти

хорошо, а если использовать промежуточную переменную.
Вовсяком случае буде выполняться быстрее, чем при создание tstringlist сдвига символов для вставки каретки, тем более по сабжу нужно создать именно массив

ЗЫ щас пересмотрел ветку с начала в 2 ты предлогал собсна тоже самое. Не (использовать же copy для вставки в массив)


Gydvin   (2006-08-21 18:41:00) [7]

последний # из строки убрать


default   (2006-08-21 18:40:00) [8]

Gydvin ©   (21.08.06 18:22) [23]
"Ну, а чем плох такой вариант"
честно говоря, лучше бы ты его не приводил...
"arr[i] := arr[i] + s[x];"
тут будут возникать перераспределения памяти


Gydvin   (2006-08-21 18:22:00) [9]

Ну, а чем плох такой вариант

procedure TForm1.Button1Click(Sender: TObject);
var
 arr: array of string;
 s: string;
 x, i: integer;
begin

 s := 'Мама#мыла#очень#большой#кусок#подоконика#от#уличной#рамы#';

 i := 0;

 for x := 1 to length(s) do if s[x] = '#' then inc(i);
 setlength(arr, i);

 i := 0;

 for x := 1 to length(s) do begin
   if s[x] = '#' then inc(i)
   else arr[i] := arr[i] + s[x];
 end;

 showmessage(arr[0]);
 showmessage(arr[1]);
 showmessage(arr[2]);
 showmessage(arr[3]);
 showmessage(arr[4]);
 showmessage(arr[5]);
 showmessage(arr[6]);
 showmessage(arr[7]);
 showmessage(arr[8]);

end;


Плохиш   (2006-08-21 16:28:00) [10]


> Селезин ©   (21.08.06 16:25) [20]

Рекомендую всё-таки посмотреть реализацию SetDelimitedText у TStrings.


Пусик   (2006-08-21 16:27:00) [11]


> Тогда вопрос, скажем pos работает быстрее, чем самоличный
> перебор по поиску разделителя или медленнее?


А тебе Pos подойдет для поиска сразу всех разделителей?;)


Селезин   (2006-08-21 16:25:00) [12]

Ну хорошо,

j:=1;
while (strResurs[j]<>'#') do inc(j);

Но смысл вопроса тот же.


Zeqfreed   (2006-08-21 16:05:00) [13]

> [18] Селезин ©   (21.08.06 15:57)


> copy(strResurs, j, 1)<>'#'

Зачем такой ужас?


Селезин   (2006-08-21 15:57:00) [14]

default
В смысле вытащить из исходника и преобразовать под себя?
Ну и так тоже иногда делаем. Вопрос в том, что надо сперва допереть что вытаскивать. И стоит ли овчинка выделки.

Типа ЛЮБОЙ алгоритм использует простой перебор? В том числе и дельфийские функции?
Тогда вопрос, скажем posработает быстрее, чем самоличный перебор по поиску разделителя или медленнее?
то бишь быстрее будет работать

j := pos('#', strResurs);

или

j:=1;
while (copy(strResurs, j, 1)<>'#') do inc(j);
end;


default   (2006-08-21 15:27:00) [15]

Селезин ©   (21.08.06 15:06) [14]
см [7]
генофонд - это исходники
в них можно посмотреть код этой функции
это куда лучше чем подбирать комментарии всяких с разных сайтов о данной проблематике...первоисточник всегда рулит


Пусик   (2006-08-21 15:26:00) [16]

Разбивка в один цикл:

function ExtractStrings(const Src: String; StrArray: TStrArray; Delim: Char): Integer;
var
 pz: Integer;
 i: Integer;
begin
 Result := -1;
 if Length(Src)=0 then
 begin
   Result := 0;
   Exit;
 end;
 pz := 1;
 i := 1;
 if Length(StrArray)=0 then SetLength(StrArray,128);
 while i<Length(Src) do
 begin
   if Src[i]=Delim then
   begin
     Inc(Result);
     if Result=Length(StrArray) then SetLength(StrArray,Length(StrArray)+128);
     StrArray[Result] := Copy(Src,pz,i-pz);
     Inc(i);
     pz := i;
   end
   else Inc(i);
 end;
 if pz<>Length(Src) then
 begin
     Inc(Result);
     if Result=Length(StrArray) then SetLength(StrArray,Length(StrArray)+1);
     StrArray[Result] := Copy(Src,pz,Length(StrArray)-pz+1);
 end;
 Inc(Result);
 SetLength(StrArray,Result);
end;


XTD   (2006-08-21 15:12:00) [17]

var t:TStringList;

begin
 t:=TStringList.create; //создаём класс
 t.text:=stringReplace('Ваша строка для разделения',' ',#13#10,[rfReplaceAll]);//мы заменяем все пробелы на символы конца строки
//теперь можно убедится что у вас строка разбина на элементы:
 showmessage(t[0]);
 showmessage(t[1]);
 showmessage(t[2]);
 showmessage(t[3]);
...
//после работы надо уничтожить класс
t.free;


Селезин   (2006-08-21 15:06:00) [18]

Хм, не знаю, как с точки зрения времени и памяти, учитывая, что придется разбирать единовременно порядка 500-5000 строк из 20-50 разделителей каждая.

default, а ссылка на описание "погрешностей" Classes.ExtractStrings есть? Дабы на грабли не наступить потом случайно.


easy   (2006-08-21 15:06:00) [19]

type TStrarray = array of string;

function explode(instr: string; const delmtr:char; var outarr: TStrarray): boolean;  //[x]
var
 len, j : integer;
 tmp:string;
begin
 j := pos(delmtr, instr);
 len := 0;
 result := false;
 if j <> 0 then begin
   while j <> 0 do begin
     tmp := copy(instr, 1, j - 1);
     SetLength(outarr, len+1);
     outarr[len] := tmp;
     inc(len);
     delete(instr, 1, j);
     j := pos(delmtr, instr);
   end;
   tmp := instr;
   SetLength(outarr, len+1);
   outarr[len] := tmp;
   result := true;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 A:TStrarray;
begin
 if explode('Мои имя фамилия отчество#мой адрес#мои интересы#мой e-mail','#',A) then
   Showmessage(A[High(A)]);
end;


Пусик   (2006-08-21 14:59:00) [20]


> Селезин ©   (21.08.06 14:56) [11]


Мне кажется, что простой проход по строке с одновременным помещением подстрок в динамический массив будет приемлимым решением с любой точки зрения.


Страницы:   1 2

Наверх

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