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

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

Удалить подстроку из очень большой строки (больше 2 ГБ ) [D7, WinXP]


Страницы:   1 2 3 4 5 6 7

*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)
А с маленькими строками она работает ?


Страницы:   1 2 3 4 5 6 7

Наверх

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