Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];
ВнизСоздание диапазонов чисел из последовательности чисел Найти похожие ветки
← →
kukuikar © (2010-04-01 09:59) [0]Есть последовательность чисел. Числа в TStrings. Например
1 2 3 4 5 10 11 12 15 17 21 25 26 27 50 1000 1051
и т.д.
Мне нужно получить все диапазоны последовательных, т.е.1-5 10-12 15 17 21 25-27 50 1000 1051
Есть функция:function CreateDiapazons(List: TStrings): String;
var
i, n1, n2, n3, n4: Integer;
tStr: String;
begin
if List.Count > 0 then
begin
n3 := 0;
for i := 0 to List.Count - 2 do
begin
n1 := StrToInt(List.Strings[i]);
n2 := StrToInt(List.Strings[i + 1]);
if n2 - n1 > 1 then
begin
tStr := tStr + List.Strings[n3] + "-" + List.Strings[i] + " ";
n3 := i + 1;
end;
end;
if n3 = 0 then
tStr := List.Strings[0] + "-" + List.Strings[List.Count - 1];
Result := Trim(tStr);
end;
end;
Только если я прогоню последовательность то получу вот что:1-5 10-12 15-15 17-17 21-21 25-27 50-50 1000-1000
Проблема 1. Немогу добиться чтобы функция включала и последнее число/диапазон.
Проблема 2. Избавится от диапазонов типа 50-50 т.е.
Помогите пожалуйст. Заранее спасибо.
← →
И. Павел © (2010-04-01 10:10) [1]> Проблема 1. Немогу добиться чтобы функция включала и последнее
> число/диапазон.
Делайте на одну итерацию больше, или исполните код цикла еще раз после его завершения.
> Проблема 2. Избавится от диапазонов типа 50-50 т.е.
if n2 - n1 > 1 then
begin
if n3<>i then tStr := tStr + List.Strings[n3] + "-" + List.Strings[i] + " "
else tStr := tStr + List.Strings[n3] + " "
n3 := i + 1;
end;
← →
kukuikar © (2010-04-01 10:20) [2]
> Делайте на одну итерацию больше, или исполните код цикла
> еще раз после его завершения.
если я сделаю на одну итерацию больше тоn2 := StrToInt(List.Strings[i + 1]);
на последнем шаге будет больше чем List.Count и соответственно ошибка...
← →
И. Павел © (2010-04-01 10:24) [3]> [2] kukuikar © (01.04.10 10:20)
Учитывайте то, что итерация последняя. К примеру так:
n1 := StrToInt(List.Strings[i]);
if i<>List.Count-1 then n2 := StrToInt(List.Strings[i + 1]);
else n2:=n1+100;
← →
kukuikar © (2010-04-01 10:40) [4]:( не получается
← →
kukuikar © (2010-04-01 10:47) [5]решил...
в цикл добавить проверку...if i = List.Count - 2 then
begin
if i - n3 > 0 then
tStr := tStr + List.Strings[n3] + "-" + List.Strings[List.Count - 1] + " "
else
tStr := tStr + List.Strings[n3] + " ";
end;
И. Павел спасибо Вам...
← →
И. Павел © (2010-04-01 10:47) [6]У меня работает:
function CreateDiapazons(List: TStrings): String;
var
i, n1, n2, n3, n4: Integer;
tStr: String;
begin
if List.Count > 0 then
begin
n3 := 0;
for i := 0 to List.Count - 1 do
begin
n1 := StrToInt(List.Strings[i]);
if i<>List.Count-1 then n2 := StrToInt(List.Strings[i + 1])
else n2:=n1+100;
if n2 - n1 > 1 then
begin
if n3<>i then tStr := tStr + List.Strings[n3] + "-" + List.Strings[i] + " "
else tStr := tStr + List.Strings[n3] + " ";
n3 := i + 1;
end;
end;
if n3 = 0 then
tStr := List.Strings[0] + "-" + List.Strings[List.Count - 1];
Result := Trim(tStr);
end;
end;
← →
kukuikar © (2010-04-01 10:49) [7]А у меня работает вот так :)
function CreateDiapazons(List: TStrings): String;
var
i, n1, n2, n3, n4: Integer;
tStr: String;
begin
if List.Count > 0 then
begin
n3 := 0;
for i := 0 to List.Count - 2 do
begin
n1 := StrToInt(List.Strings[i]);
n2 := StrToInt(List.Strings[i + 1]);
if n2 - n1 > 1 then
begin
if n3 <> i then
tStr := tStr + List.Strings[n3] + "-" + List.Strings[i] + " "
else
tStr := tStr + List.Strings[n3] + " ";
n3 := i + 1;
end;
if i = List.Count - 2 then
begin
if i - n3 > 0 then
tStr := tStr + List.Strings[n3] + "-" + List.Strings[List.Count - 1] + " "
else
tStr := tStr + List.Strings[n3] + " ";
end;
end;
if n3 = 0 then
tStr := List.Strings[0] + "-" + List.Strings[List.Count - 1];
Result := Trim(tStr);
end;
end;
← →
Sha © (2010-04-01 14:01) [8]Тоже написал
function ShaCreateDiapazons(List: TStrings): string;
var
i, iLast: integer;
v0, v1: integer;
s0, s1: string;
begin;
v0:=0;
Result:="";
iLast:=List.Count-1;
for i:=0 to iLast do begin;
s1:=List.Strings[i];
v1:=StrToInt(s1);
if (v1<>v0+1) or (i=0) or (i=iLast) then begin;
if s0<>"" then Result:=Result + "-" + s0;
s0:="";
if Result="" then Result:=s1 else Result:=Result + #32 + s1;
end
else s0:=s1;
v0:=v1;
end;
end;
← →
Sha © (2010-04-01 15:05) [9]Исправил ошибку при обработке последнего числа
function ShaCreateDiapazons(List: TStrings): string;
var
i, iLast: integer;
v0, v1: integer;
s0, s1: string;
begin;
v0:=0;
Result:="";
iLast:=List.Count-1;
for i:=0 to iLast do begin;
s1:=List.Strings[i];
v1:=StrToIntDef(s1,MaxInt);
if (i=0) or (i=iLast) or (v1<>v0+1) then begin;
if i=0 then Result:=s1
else if v1=v0+1 then Result:=Result + "-" + s1
else begin;
if s0<>"" then Result:=Result + "-" + s0;
Result:=Result + #32 + s1;
end;
s0:="";
end
else s0:=s1;
v0:=v1;
end;
end;
← →
kukuikar © (2010-04-02 08:43) [10]а вот такой вопрос. с чем будет работать быстрее, с массивами или с tstrings? размерность будет большая до 200 тысяч строк...
← →
И. Павел © (2010-04-02 08:50) [11]ИМХО всех быстрее и компактнее - с массивом чисел (особенно если алгоритм проводит IntToStr несколько раз для одного и того же элемента). Массив строк по крайней мере будет не медленнее, чем TString. Хотя можно просто проверить и посмотреть - будет ли существенное различие в быстродействии (мне кажетcя, что 20000 чисел - это немного).
← →
И. Павел © (2010-04-02 08:54) [12]Ну и, конечно, если использовать класс - то лучше TStringList, а не TStrings от Memo.
← →
kukuikar © (2010-04-02 09:27) [13]Изначально задача стоит такая.
Текстовый файл. Сосоит из разного количества блоков. Каждый блок со своими правилами, со строками разной дляны и т.п.
Пока читаю в StringList, но приходится переводить из строк в числа и обратно по нескольку раз... (в итоге получаю тоже текстовик, только с другой структурой)
Думаю поробовать с массивами....
И кстати, придется делать так, чтобы каждый элемент массива был массивом с элементами количеством от 2 до 8 штук...
← →
Sha © (2010-04-02 09:38) [14]> Sha © (01.04.10 15:05) [9]
Убрал повторные проверки:
function ShaCreateDiapazons(List: TStrings): string;
var
i, iLast: integer;
v0, v1: integer;
s0, s1: string;
begin;
v0:=0;
Result:="";
iLast:=List.Count-1;
for i:=0 to iLast do begin;
s1:=List.Strings[i];
v1:=StrToIntDef(s1,MaxInt);
if i=0 then Result:=s1
else if v1<>v0+1 then begin;
if s0<>"" then Result:=Result + "-" + s0;
Result:=Result + #32 + s1;
s0:="";
end
else if i=iLast then Result:=Result + "-" + s1
else s0:=s1;
v0:=v1;
end;
end;
> kukuikar © (02.04.10 08:43) [10]
> с чем будет работать быстрее, с массивами или с tstrings?
> размерность будет большая до 200 тысяч строк
Тогда стоит задуматься, а верно ли выбраны структуры данных для твоей задачи? Массив чисел здесь предпочтительнее в качестве входных и выходных данных.
Если все же требуется работать с массивом строк и при этом нужна скорость, то нужно менять алгоритм с целью уменьшения числа перераспределений памяти. Операции сцепления строк заменить на что-нибудь более быстрое.
← →
kukuikar © (2010-04-02 09:39) [15]
> Sha © (01.04.10 15:05) [9]
Спасибо...
← →
kukuikar © (2010-04-02 09:45) [16]
> Тогда стоит задуматься, а верно ли выбраны структуры данных
> для твоей задачи? Массив чисел здесь предпочтительнее в
> качестве входных и выходных данных.
с исходным файлом выбора нет. он приходит таким какой он есть...
например вот такой:
http://perepetsky.ru/constr2.zip
а на выходе должен быть такой:
http://perepetsky.ru/constr2_N.zip
Так что лопатить все надо...
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.058 c