![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Создание диапазонов чисел из последовательности чисел [D7, XP]
kukuikar © (2010-04-01 09:59:00)Есть последовательность чисел. Числа в 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 т.е.
Помогите пожалуйст. Заранее спасибо.
kukuikar (2010-04-02 09:45:00) [1]
> Тогда стоит задуматься, а верно ли выбраны структуры данных
> для твоей задачи? Массив чисел здесь предпочтительнее в
> качестве входных и выходных данных.
с исходным файлом выбора нет. он приходит таким какой он есть...
например вот такой:
http://perepetsky.ru/constr2.zip
а на выходе должен быть такой:
http://perepetsky.ru/constr2_N.zip
Так что лопатить все надо...
kukuikar (2010-04-02 09:39:00) [2]
> Sha © (01.04.10 15:05) [9]
Спасибо...
Sha (2010-04-02 09:38:00) [3]> 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:27:00) [4]Изначально задача стоит такая.
Текстовый файл. Сосоит из разного количества блоков. Каждый блок со своими правилами, со строками разной дляны и т.п.
Пока читаю в StringList, но приходится переводить из строк в числа и обратно по нескольку раз... (в итоге получаю тоже текстовик, только с другой структурой)
Думаю поробовать с массивами....
И кстати, придется делать так, чтобы каждый элемент массива был массивом с элементами количеством от 2 до 8 штук...
И. Павел (2010-04-02 08:54:00) [5]Ну и, конечно, если использовать класс - то лучше TStringList, а не TStrings от Memo.
И. Павел (2010-04-02 08:50:00) [6]ИМХО всех быстрее и компактнее - с массивом чисел (особенно если алгоритм проводит IntToStr несколько раз для одного и того же элемента). Массив строк по крайней мере будет не медленнее, чем TString. Хотя можно просто проверить и посмотреть - будет ли существенное различие в быстродействии (мне кажетcя, что 20000 чисел - это немного).
kukuikar (2010-04-02 08:43:00) [7]а вот такой вопрос. с чем будет работать быстрее, с массивами или с tstrings? размерность будет большая до 200 тысяч строк...
Sha (2010-04-01 15:05:00) [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:=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;
Sha (2010-04-01 14:01:00) [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:=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;
kukuikar (2010-04-01 10:49:00) [10]А у меня работает вот так :)
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;
kukuikar (2010-04-01 10:47:00) [11]решил...
в цикл добавить проверку...
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:00) [12]У меня работает:
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:40:00) [13]:( не получается
И. Павел (2010-04-01 10:24:00) [14]> [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:20:00) [15]
> Делайте на одну итерацию больше, или исполните код цикла
> еще раз после его завершения.
если я сделаю на одну итерацию больше то
n2 := StrToInt(List.Strings[i + 1]);на последнем шаге будет больше чем List.Count и соответственно ошибка...
И. Павел (2010-04-01 10:10:00) [16]> Проблема 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;