Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.49 MB
Время: 0.066 c
2-1266247298
AndrewGm
2010-02-15 18:21
2010.08.27
Excel


2-1269889255
HRustBB
2010-03-29 23:00
2010.08.27
Нужен компонент для отображения схеммы данных


15-1267567565
Delphi5.01
2010-03-03 01:06
2010.08.27
Редакт. настр. прокси для Firefox и Opera (решение оплачивается)


2-1269008966
allrussia
2010-03-19 17:29
2010.08.27
Как отловить нажатие кнопки во время появления PopupMenu


15-1274472622
RWolf
2010-05-22 00:10
2010.08.27
Induc v2.0





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский