Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.03.27;
Скачать: CL | DM;

Вниз

разделить строку   Найти похожие ветки 

 
cross   (2010-12-28 12:21) [0]

как быстро разделить строку на подстроки по 2048 символов?

вот мой вариант:


var
 S: string;
 N, I: Integer;
 SL: TStrings;
begin
 SL := TStringList.Create;
 try
   N := 1;
   for I := 1 to length(S) do
   begin
     if I mod 2048 = 0 then
     begin
       SL.Add(Copy(S, N, I));
       Inc(N, 2048);
     end;
   end
   ShowMessage(SL.Text);
 finally
   SL.Free;
 end;
end;


 
Ega23 ©   (2010-12-28 12:23) [1]

Copy, SetLength, Length + F1


 
Ega23 ©   (2010-12-28 12:27) [2]


> cross   (28.12.10 12:21)  


Да, кстати: в твоём коде ошибка.


 
Плохиш ©   (2010-12-28 12:27) [3]

Кроме цикла for в делфи есть ещë минимум два типа циклов. И позиции для деленя строки искать не требуется, т.к. они заданы в условии.


 
Dennis I. Komarov ©   (2010-12-28 12:33) [4]

пока не конец строки вставляем в (вычисляем куда) позицию строки #13#10


 
Ega23 ©   (2010-12-28 12:35) [5]


> пока не конец строки вставляем в (вычисляем куда) позицию
> строки #13#10

А с чего ты взял, что в изначальной строке не может содержаться этих символов?  :)


 
cross   (2010-12-28 13:09) [6]

А если так?


for i := 0 to Length(S) div 2048 do
   SL.Add(Copy(S, I * 2048 + 1, 2048));


 
Ega23 ©   (2010-12-28 13:34) [7]


> А если так?


1. А почему строка не может быть меньше 2048?
2. Вот ANSI-строка (в кавычках)
"мама
мыла
раму"
какова её длина? :)


 
cross   (2010-12-28 13:43) [8]

мне собственно все это нужно, чтобы записывать и считывать длинные строки из ini-файла, в ReadString ограничение 2048, + возможно придется записывать строки длинной > 65535.


 
Ega23 ©   (2010-12-28 13:45) [9]


> мне собственно все это нужно, чтобы записывать и считывать
> длинные строки из ini-файла, в ReadString ограничение 2048,
>  + возможно придется записывать строки длинной > 65535.

Ini-файлы для этого не предназначены, тебе уже вроде советовали либо формат сменить, либо из Кладовки взять.


 
Полвторого   (2010-12-28 13:50) [10]

var A: integer;
...

A := (Length(S) shr 11) - 1; // обязательно знаковый тип!
for i = 0 to A do SL.Add(Copy(S, 1+(i shl 11), 2048));
SL.Add(Copy(S, 1+((A+1) shl 11), Length(S) and (2048-1)));


 
Dennis I. Komarov ©   (2010-12-28 14:02) [11]


> А с чего ты взял, что в изначальной строке не может содержаться
> этих символов?  :)

Ну откуда я знаю чего там изначально. Ну есть - ладно, придумаем свой разделитеть :) #1#2#3#2#1 пойдет?


 
Ega23 ©   (2010-12-28 14:03) [12]

Блин.
Ну выполните уже простой код:

procedure TForm3.Button1Click(Sender: TObject);
var
 sl: TStringList;
begin
 sl := TStringList.Create;
 try
   sl.Add("мама" + #13#10 + "мыла" + #13#10 + "раму");
   ShowMessage(sl.Text);
 finally
   sl.Free;
 end;
end;


Чего стоит хранение всей вашей разбивки, если в этих 2048 чарах может встретиться комбинация #13#10?


 
без 15 2   (2010-12-28 14:05) [13]

SetLength(s2, LenS);
 CopyMemory( addr(s2[1]), addr(s[1+NumIter*LenS]), LenS);


 
Palladin ©   (2010-12-28 14:16) [14]


> без 15 2   (28.12.10 14:05) [13]

по рукам получишь


 
Dennis I. Komarov ©   (2010-12-28 14:19) [15]


> Чего стоит хранение всей вашей разбивки, если в этих 2048
> чарах может встретиться комбинация #13#10?

Тогда логичный вопрос: А зачем...?


 
Ega23 ©   (2010-12-28 14:23) [16]


> Тогда логичный вопрос: А зачем...?


Что зачем?
Если мы решаем абстрактную задачу по быстрой разбивке произвольной строки произвольной длины на куски по 2048 символов - это одно. Собственно, изначальный вопрос был сформулирован именно так.
Если это какой-то magic-механизм чтения квази-ini-файла (т.е. ректальная тонзиллэктомия), то это совсем другое.
Автор пока шифруется.


 
cross   (2010-12-28 14:34) [17]


> решаем абстрактную задачу по быстрой разбивке произвольной
> строки произвольной длины на куски по 2048 символов


 
Dennis I. Komarov ©   (2010-12-28 14:42) [18]

Если решаем абстрактную задачу [0] то разбить на "подстроки" не получится, т.к. в абстрактной строке может быть любое сочетание символов, т.е. надо тупо работать с исходной строкой для извлечение конкретной подстроки.
Copy(Str, i*L+1, L)
В реальности это дурь...


 
Ega23 ©   (2010-12-28 15:09) [19]


> cross   (28.12.10 14:34) [17]
> > решаем абстрактную задачу по быстрой разбивке произвольной
> > строки произвольной длины на куски по 2048 символов


Ну вроде что-то типа:

type
 TResArr = array of string;

procedure SplitString2048(InStr: string; var ResArray: TResArr);
var
 i, cnt, sLen: Integer;
begin
 sLen := Length(InStr);
 cnt := sLen shr 11;
 if (sLen and 2047) <> 0 then
   Inc(cnt);
 SetLength(ResArray, cnt);

 for i := 0 to cnt - 1 do
   ResArray[i] := Copy(InStr, (i shl 11) + 1, 2048);
end;


 
cross   (2010-12-28 15:44) [20]

последнее, что хочу уточнить, почему 11?

sLen shr 11


 
Полвторого   (2010-12-28 15:49) [21]

2048 = 2&#185;&#185;.


 
han_malign   (2010-12-28 16:03) [22]


> cnt := sLen shr 11;
>  if (sLen and 2047) <> 0 then
>    Inc(cnt);

 cnt:= (sLen + modulo-1) div modulo;
если modulo - есть константа и степень двойки, компилятор сам преобразует это в сдвиговую операцию - не надо делать левую оптимизацию в ущерб семантике...


 
Ega23 ©   (2010-12-28 16:21) [23]

cnt:= (sLen + modulo-1) div modulo;

Ну не знаю...


Unit3.pas.126: ShowMessage(IntToStr(Value div 2));
004B7E7E 8D55FC           lea edx,[ebp-$04]
004B7E81 8BC3             mov eax,ebx
004B7E83 D1F8             sar eax,1
004B7E85 7903             jns $004b7e8a
004B7E87 83D000           adc eax,$00
004B7E8A E889A7F5FF       call IntToStr
004B7E8F 8B45FC           mov eax,[ebp-$04]
004B7E92 E8A945FBFF       call ShowMessage

Unit3.pas.126: ShowMessage(IntToStr(Value shr 1));
004B7E7E 8D55FC           lea edx,[ebp-$04]
004B7E81 8BC3             mov eax,ebx
004B7E83 D1E8             shr eax,1
004B7E85 E88EA7F5FF       call IntToStr
004B7E8A 8B45FC           mov eax,[ebp-$04]
004B7E8D E8AE45FBFF       call ShowMessage


 
Ega23 ©   (2010-12-28 16:46) [24]

В догонку к [23] - Optimisation в True в опциях выставлено.


 
Игорь Шевченко ©   (2010-12-28 16:54) [25]


> Ну не знаю...


разница будет при отрицательных числах


 
han_malign   (2010-12-28 16:55) [26]


> Ну не знаю...

- размер со знаком всегда вызывал у меня недоумение...


 
Jeer ©   (2010-12-28 16:57) [27]

Да я бы вообще не делил :)
Ну есть строка большая, есть число секций по 2048.
Вот нужную секцию и выбирать по номеру.


 
Anatoly Podgoretsky ©   (2010-12-28 17:31) [28]

Вариант с div правильный, а с shr ошибка. Применим только для положительных чисел.


 
Leonid Troyanovsky ©   (2010-12-28 18:42) [29]


> cross   (28.12.10 12:21)  

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

SetString

--
Regardes, LVT.


 
Полвторого   (2010-12-28 19:55) [30]


> есть строка большая, есть число секций по 2048.
> Вот нужную секцию и выбирать по номеру.

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


> Вариант с div правильный, а с shr ошибка. Применим только
> для положительных чисел.

Ну я, конечно, дядь Толь, звиняюсь — но отрицательная длина строки это нечто из области мракобесия.


 
Palladin ©   (2010-12-28 20:05) [31]

если встречается мракобесие, то обычно это означает отсутствие значения, тогда как ноль - пустая строка


 
Anatoly Podgoretsky ©   (2010-12-28 20:11) [32]

> Полвторого  (28.12.2010 19:55:30)  [30]

Дело не в строках, функция работает с любыми числами. И shr будет давать
ошибку, неверные данные. А div будет работать правильно.


 
Ega23 ©   (2010-12-28 20:19) [33]


> Дело не в строках, функция работает с любыми числами. И
> shr будет давать
> ошибку, неверные данные. А div будет работать правильно.
>


ээээ. Пардон, какая функция ошибку будет давать?


 
Anatoly Podgoretsky ©   (2010-12-28 20:39) [34]

> Ega23  (28.12.2010 20:19:33)  [33]

Оператор SHR


 
Ega23 ©   (2010-12-28 20:42) [35]

Я ещё раз пардоню, но где у меня в [19] могут быть отрицательные значения?

Подумал. Это в смысле входная строка больше двух гигов?


 
Anatoly Podgoretsky ©   (2010-12-28 20:52) [36]


> Ega23 ©   (28.12.10 20:42) [35]

Строку ты приплел, а мы обсуждали это.


> cnt:= (sLen + modulo-1) div modulo;
> если modulo - есть константа и степень двойки, компилятор
> сам преобразует это в сдвиговую операцию - не надо делать
> левую оптимизацию в ущерб семантике...

Как видишь здесь никаких строк, а только деление по модулю, без привлечения подозрительного SHR


 
Ega23 ©   (2010-12-28 20:59) [37]


> Как видишь здесь никаких строк, а только деление по модулю,
>  без привлечения подозрительного SHR


Ну дык han_malign sLen из того поста взял, где sLen = Length(InputStr)
З.Ы. Я наверное серьёзно не догоняю, о чём спич. Тем более что я уже пива насосался.


 
Anatoly Podgoretsky ©   (2010-12-28 21:05) [38]

> Ega23  (28.12.2010 20:59:37)  [37]

Пиво зло, когда рядом туалета нет.

Тезис был такой, что не надо использовать лебую оптимизацию, в лице SHR и
ниже было доказано, что это работает при очень серьезных огрнаинчения, а с
DIV проблемы нет, там видно, что задействован тоже сдвиг, только
арифметический сдвиг, с коррекцией результата в зависимости от знака. То
есть дело не в самих сдвигах, а в их не нужности и даже вредности.
Оптимизатор Дельфи с честью справился с задачей.



Страницы: 1 вся ветка

Текущий архив: 2011.03.27;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.01 c
6-1236003005
_bass
2009-03-02 17:10
2011.03.27
Интернет активность.


15-1292367809
Германн
2010-12-15 02:03
2011.03.27
Странный глюк тут обнаружился.


15-1292323166
ixen
2010-12-14 13:39
2011.03.27
Setup и Firebird


15-1291881642
DiamondShark
2010-12-09 11:00
2011.03.27
Дай палец -- откусят руку.


15-1291973556
12
2010-12-10 12:32
2011.03.27
сломался ctrl+click в IDE. TLabel, ctrl+click на нем, и.. ничего.