Форум: "Начинающим";
Текущий архив: 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¹¹.
← →
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