![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Разбиение строки в масив [D7]
Селезин © (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]
Мне кажется, что простой проход по строке с одновременным помещением подстрок в динамический массив будет приемлимым решением с любой точки зрения.