![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Удалить подстроку из очень большой строки (больше 2 ГБ ) [D7, WinXP]
*Ray* © (2007-09-07 18:42:00)Здравствуйте, уважаемые мастера! Столкнулся со стандартной вроде бы задачей, но с интересного ракурса. Задача проста: Нужно написать функцию, удаляющую все вхождение подстроки в строке. Но есть одно условие: строка очень большая - около 2 Гб, может и больше, и нужно чтобы функция была максимально оптимизирована. Вот здесь я немного теряюсь.
Я сделал так:
Function Del_Str (longstring, string: string):string;
begin
while pos(str, longsting)>0 do
begin
del(longstring, pos(str, longstring), length(str)) ;
end;
result:=longstring;
end;
Функция работает, но одно даже присваивание result значение longstring займет в памяти 4 Гб, если строка 2 Гб. Не говря уже о других операциях. Надо что-то придумать.
Заранее всем ольшое спасибо за предложенные варианты!
Юрий Зотов (2007-09-07 19:20:00) [121]> Palladin © (07.09.07 19:02) [8]
Тоже есть одно но... я говорил о присвоении (на что явно указал цитатой) и нигде ни разу не говорил об изменении.
Что же касаетеся изменений (т.е., сабжа), то сама постановка задачи представляется настолько странной, что лучше промолчать. Вот почему.
4 Гб - вся память. Из них верхние 2 Гб и нижние 64 Кб резервируются системой. Минус статическая память и стек. Под хип остается явно менее 2 Гб и поэтому непонятно, откуда вообще взялась строка длиной "около 2 Гб, может и больше".
Тут явно что-то недосказано, поэтому - какие можно дать рекомендации, не зная задачи?
*Ray* (2007-09-07 19:20:00) [122]to Инс
> Оно вообще не будет работать на Win32. Только если проецировать
> строку в память из файла частями.
Объясните пожалуйста поподробнее. Прошу прощения, что сразу не заметил.
*Ray* (2007-09-07 19:19:00) [123]2 Palladin:
> ну во первых вопрос, тебе только одну подстроку str (кстати
> тоже не рекомендую использовать идентификатор с таким названием)
> удалить из строки или все?
нужно удалить все вхождения подстроки. А почему нельзя использовать даже "str?
Palladin (2007-09-07 19:16:00) [124]ну во первых вопрос, тебе только одну подстроку str (кстати тоже не рекомендую использовать идентификатор с таким названием) удалить из строки или все?
Инс (2007-09-07 19:15:00) [125]
> [10] *Ray* © (07.09.07 19:13)
Вы читать вообще умеете? [4] и [7] прочтите еще раз. Будут вопросы по этому поводу - задавайте.
*Ray* (2007-09-07 19:15:00) [126]точнее
Function Del_Str (var longstring, str: string):string;
var k:integer;
begin
k:=pos(str, longsting);
while k>0 do
begin
del(longstring, k, length(str)) ;
k:=pos(str, longsting);
end;
result:=longstring;
end;
*Ray* (2007-09-07 19:13:00) [127]to Riply:
Например, не считать pos(str, longstring) два раза :)
to Palladin:
> что бы удалить что то из подстроки, без лишнего расхода
> памяти придется таки использовать var в описании параметров
> процедуры или функции
тогда получается так:
Function Del_Str (var longstring, str: string):string;
var k:integer;
begin
k:=pos(str, longsting);
while k>0 do
begin
del(longstring, k, length(str)) ;
end;
result:=longstring;
end;
Что-нибудь еще можно улучшить?
DVM (2007-09-07 19:08:00) [128]
> А если обойтись без файла, можно как то дополнительно оптимизировать?
То, что ты написал переписать вообще. Кстати, ты ведь ищешь что-то фиксированное, если да, то можно написать функции, работющие быстрее Pos().
А насчет файла. Зачем тебе такая строка в памяти. Ты же ее все равно потом сохранять будешь. Или нет?
Palladin (2007-09-07 19:02:00) [129]
> Юрий Зотов © (07.09.07 18:55) [2]
есть одно но... даже несколько...
во первых функции Del_Str (longstring, string: string) существовать не может, бо string reserved word, во вторых операция со строкой не переданной как var приводит к ее дубляжу и модификации дубликата... особенно при выполнении del()... информация переданная в идентификаторе параметром должна остаться не тронутой...
экзампл
procedure pp(s:String);
Begin
s:=copy(s,1,1);
showmessage(s);
End;
procedure TForm1.Button1Click(Sender: TObject);
var
s:String;
begin
s:='12345';
pp(s);
showmessage(s);
end;
что бы удалить что то из подстроки, без лишнего расхода памяти придется таки использовать var в описании параметров процедуры или функции
Riply (2007-09-07 19:01:00) [130]> [5] *Ray* © (07.09.07 18:59)
Например, не считать pos(str, longstring) два раза :)
Инс (2007-09-07 19:01:00) [131]
> [5] *Ray* © (07.09.07 18:59)
Оно вообще не будет работать на Win32. Только если проецировать строку в память из файла частями.
*Ray* (2007-09-07 18:59:00) [132]А если обойтись без файла, можно как то дополнительно оптимизировать? ПУсть даже хоть немного, но лучше? Чтобы быстрее работало.
Инс (2007-09-07 18:57:00) [133]
> Задача проста: Нужно написать функцию, удаляющую все вхождение
> подстроки в строке. Но есть одно условие: строка очень большая
> - около 2 Гб, может и больше
И как же она уместится в виртуальном адресном пространстве процесса на Win32?
> Функция работает, но одно даже присваивание result значение
> longstring займет в памяти 4 Гб, если строка 2 Гб.
Нет. result:=longstring; - это просто копирование указателя.
DVM (2007-09-07 18:56:00) [134]
> *Ray* ©
Лучше строку хранить в файле на диске и далее создать временный файл и переписывать туда все, кроме того, что требуется удалять. После переименовать исходный файл, на его место переименовать временный и если все ок, то удалить исходный.
Юрий Зотов (2007-09-07 18:55:00) [135]> *Ray* © (07.09.07 18:42)
> одно даже присваивание result значение longstring займет в памяти 4 Гб,
> если строка 2 Гб.
Не займет. При присваивании строковых переменных копия строки не создается, просто увеличивается счетчик ссылок на строку.
Riply (2007-09-07 18:47:00) [136]> [0] *Ray* © (07.09.07 18:42)
А с маленькими строками она работает ?