Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.08.27;
Скачать: CL | DM;

Вниз

Создание диапазонов чисел из последовательности чисел   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.049 c
3-1241681644
abhtr
2009-05-07 11:34
2010.08.27
Нужна срочная помошь!!!


4-1234253553
OlegNik
2009-02-10 11:12
2010.08.27
Доп. информация об устройствах.


2-1273322142
Родион
2010-05-08 16:35
2010.08.27
переписать из с++ в делфи


10-1165502198
YCH.Del
2006-12-07 17:36
2010.08.27
Excel, реализовать в Delphi VB шный оператор Set


2-1268891918
Den
2010-03-18 08:58
2010.08.27
Параметр не имеет значения по умолчанию