Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2011.03.27;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.004 c
8-1211198951
Ganda
2008-05-19 16:09
2011.03.27
FastReport 3.0 + Bmp


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


1-1249831819
dmitry_12_08_73
2009-08-09 19:30
2011.03.27
Как скопировать клиентскую область окна в bitmap


2-1293463778
Mitroshin
2010-12-27 18:29
2011.03.27
Возможно ли использовать строку STFilter в TDBGridEh как Edit-ы?


2-1293457941
Тимоха111
2010-12-27 16:52
2011.03.27
case + pagecontrol, ordinal type required





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский