![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
разделить строку
cross © (2010-12-28 12:21:00)как быстро разделить строку на подстроки по 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;
Anatoly Podgoretsky (2010-12-28 21:05:00) [1]> Ega23 (28.12.2010 20:59:37) [37]
Пиво зло, когда рядом туалета нет.
Тезис был такой, что не надо использовать лебую оптимизацию, в лице SHR и
ниже было доказано, что это работает при очень серьезных огрнаинчения, а с
DIV проблемы нет, там видно, что задействован тоже сдвиг, только
арифметический сдвиг, с коррекцией результата в зависимости от знака. То
есть дело не в самих сдвигах, а в их не нужности и даже вредности.
Оптимизатор Дельфи с честью справился с задачей.
Ega23 (2010-12-28 20:59:00) [2]
> Как видишь здесь никаких строк, а только деление по модулю,
> без привлечения подозрительного SHR
Ну дык han_malign sLen из того поста взял, где sLen = Length(InputStr)
З.Ы. Я наверное серьёзно не догоняю, о чём спич. Тем более что я уже пива насосался.
Anatoly Podgoretsky (2010-12-28 20:52:00) [3]
> Ega23 © (28.12.10 20:42) [35]
Строку ты приплел, а мы обсуждали это.
> cnt:= (sLen + modulo-1) div modulo;
> если modulo - есть константа и степень двойки, компилятор
> сам преобразует это в сдвиговую операцию - не надо делать
> левую оптимизацию в ущерб семантике...
Как видишь здесь никаких строк, а только деление по модулю, без привлечения подозрительного SHR
Ega23 (2010-12-28 20:42:00) [4]Я ещё раз пардоню, но где у меня в [19] могут быть отрицательные значения?
Подумал. Это в смысле входная строка больше двух гигов?
Anatoly Podgoretsky (2010-12-28 20:39:00) [5]> Ega23 (28.12.2010 20:19:33) [33]
Оператор SHR
Ega23 (2010-12-28 20:19:00) [6]
> Дело не в строках, функция работает с любыми числами. И
> shr будет давать
> ошибку, неверные данные. А div будет работать правильно.
>
ээээ. Пардон, какая функция ошибку будет давать?
Anatoly Podgoretsky (2010-12-28 20:11:00) [7]> Полвторого (28.12.2010 19:55:30) [30]
Дело не в строках, функция работает с любыми числами. И shr будет давать
ошибку, неверные данные. А div будет работать правильно.
Palladin (2010-12-28 20:05:00) [8]если встречается мракобесие, то обычно это означает отсутствие значения, тогда как ноль - пустая строка
Полвторого (2010-12-28 19:55:00) [9]
> есть строка большая, есть число секций по 2048.
> Вот нужную секцию и выбирать по номеру.
И, кстати, очень здравая мысль.
Не требует вообще никаких манипуляций над исходной строкой.
> Вариант с div правильный, а с shr ошибка. Применим только
> для положительных чисел.
Ну я, конечно, дядь Толь, звиняюсь — но отрицательная длина строки это нечто из области мракобесия.
Leonid Troyanovsky (2010-12-28 18:42:00) [10]
> cross (28.12.10 12:21)
> как быстро разделить строку на подстроки по 2048 символов?
SetString
--
Regardes, LVT.
Anatoly Podgoretsky (2010-12-28 17:31:00) [11]Вариант с div правильный, а с shr ошибка. Применим только для положительных чисел.
Jeer (2010-12-28 16:57:00) [12]Да я бы вообще не делил :)
Ну есть строка большая, есть число секций по 2048.
Вот нужную секцию и выбирать по номеру.
han_malign (2010-12-28 16:55:00) [13]
> Ну не знаю...
- размер со знаком всегда вызывал у меня недоумение...
Игорь Шевченко (2010-12-28 16:54:00) [14]
> Ну не знаю...
разница будет при отрицательных числах
Ega23 (2010-12-28 16:46:00) [15]В догонку к [23] - Optimisation в True в опциях выставлено.
Ega23 (2010-12-28 16:21:00) [16]
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
han_malign (2010-12-28 16:03:00) [17]
> cnt := sLen shr 11;
> if (sLen and 2047) <> 0 then
> Inc(cnt);
cnt:= (sLen + modulo-1) divmodulo;
еслиmodulo- есть константа и степень двойки, компилятор сам преобразует это в сдвиговую операцию - не надо делать левую оптимизацию в ущерб семантике...
Полвторого (2010-12-28 15:49:00) [18]2048 = 2¹¹.
cross (2010-12-28 15:44:00) [19]последнее, что хочу уточнить, почему 11?
sLen shr 11
Ega23 (2010-12-28 15:09:00) [20]
> 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;