(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Класс целочисленных списков TIntList

Источник: delphikingdom
Владимир Коднянко

Автор: Владимир Коднянко, королевство Delphi

В Delphi есть класс TStringList для работы со списком строк, который использую весьма часто. Не реже, если не чаще, приходится обращаться к целочисленным массивам. Однако класса, подобного TStringList, или достаточно полного набора алгоритмов по работе с целочисленными массивами не нашел. Предлагаемый класс TIntList, быть может, окажется полезным не только мне. Надеюсь, заинтересованные читатели поделятся своими замечаниями, выскажут предложения по улучшению кода, возможно, обнаружат ошибки и сообщат о них.

Ядром класса является массив целых с пользовательским типом TIntVec. Кроме него используются две переменные FSorted (-1 - массив отсортирован по невозрастанию/убыванию, 0 - не сортирован, 1 - отсортирован по неубыванию/возрастанию) и FCompressed (true - массив не содержит одинаковых элементов). Имена подпрограмм дают достаточное представление о их назначении, тем не менее некоторым из них необходимо дать краткое пояснение.

property Count: Integer read FCount; число элементов массива;
property Sorted: Integer read FSorted; упомянутый призак сортировки;
property Compressed: boolean read FCompressed; содержит ли повторяющиеся элементы;
procedure AddInt(L: Integer); overload; dynamic; добавляет элемент;
procedure Add(L: array of Integer); overload; dynamic; добавляет массив;
procedure Add(L: TIntList); overload; dynamic; добавляет список;
function Add(s: String): Integer; overload; выделяет целые из строки и добавляет их;
function AddIntList(L: Integer): TIntList; overload; dynamic; то же с созданием списка;
function AddIntAsNew(L: Integer): boolean; virtual; добавляет целое, если его в списке нет;
procedure Assign(L: TIntList); overload; dynamic; очистка и добавление
function AsString: String; virtual; строка констант с разделителем-пробелом;
function Average: Extended; virtual; среднее арифметическое;
function Change(L1, L2: TIntList): Integer; overload; virtual; замена L1 на L2 всюду;
function ChangeList(L1, L2: TIntList): TIntList; overload; то же с созданием списка;
procedure Clear; очистка списка;
procedure Compress; virtual; удаление повторяющихся элементов;
procedure Copy(Index, Count: Integer); копирование фрагмента массива;
procedure Delete(Index: Integer); virtual; удаление элемента;
function DeleteAll(L: Integer): Integer; virtual; удаление элементов, равных L;
function DeleteFirst(L: Integer): boolean; virtual; удаление первого, равного L;
function DeleteLast(L: Integer): boolean; virtual; удаление последнего, равного L;
procedure DeleteRange(Index1, Index2: Integer); virtual; удаление фрагмента;
function FindMax(var Index: Integer): boolean; virtual; поиск наибольшего элемента;
function FindMin(var Index: Integer): boolean; virtual; поиск наименьшего элемента;
function GetIntVec: TIntVec; dynamic; возвращает массив;
function IndexOf(L: TIntList): Integer; overload; virtual; индекс элемента, массива, списка
function IndexesOf(L: TIntList): TIntList; overload; virtual; список индексов;
function IntCount(L: TIntList): Integer; overload; virtual; количество вхождений;
function IntCount2(L: TIntList): Integer; overload; virtual; количество непересекающихся вхождений;
function Insert(L: TIntList; Index: Integer): boolean; overload; вставка с указанного места;
function InsertList(L: TIntList; Index: Integer): TIntList; overload; то же с созданием списка
function IsEqual(b: TIntList): boolean; virtual; проверка на совпадение;
function Module: Extended; virtual; модуль математического вектора;
procedure Range(Index1, Index2: Integer); dynamic; диапазон (часть массива);
function ReadList(FileName: String): TIntList; чтение из файла;
procedure SortUp; virtual; сортировка по неубыванию/возрастанию;
procedure SortDown; virtual; сортировка по невозрастанию/убыванию;
function Sum: Integer; virtual; сумма элементов;
procedure Trunc(Count: Integer); обрезка;
procedure Turn; virtual; разворот массива;
procedure Write(FileName: String); запись в файл.

Несколько примеров использования класса для var q, w: TIntList; s: String; j1, j2: Integer.

q.Assign([3,4,44,3,4,6,4,8,1,3,4,5,3,4]);
w.Assign([3,4]);
s := q.IndexesOf(w).AsString;
Список индексов q, начиная с которых найден w.
Вернёт s = '0 3 9 12'.
q.Assign([73,4,44,3,4,6,4,8,1,3,4,5,3,4]);
s := q.Trunc(5).SortUpList.TurnList.AsString;
Обрезает q до 5 элементов, сортирует, разворачивает.
Вернёт s = '73 44 4 4 3'.
q.Assign([1,1,1,1,1,1,1,1]); w.Assign([1,1,1]);
j1 := q.IntCount(w); j2 := q.IntCount2(w);
Вернёт j1 = 6 (всего вхождений w в q), j2 = 2
(непересекающихся вхождений w в q).
s:= 'q+345sd6345 877 wrt 235 656-655+45er-9';
q.Assign([1001,1002]);
s := q.AddList(s).AsString;
Добавляет к списку константы, извлеченные из строки.
Вернёт s = '1001 1002 345 6345 877 235 656 -655 45 -9'.
q.Assign([44,1,4,6,7,8,1,3,1,5,6]);
s:= q.CompressList.AsString;
Строка элементов сжатого массива.
Вернёт s = '44 1 4 6 7 8 3 5'. Сам q не изменится.
q.Assign([1,4,5,3,1,8,4,5,3,3,1,3,4,5,3,3]);
ss:= q.ChangeList([4,5,3],[98,99]).AsString;
Замена фрагмента [4,5,3] на [98,99].
Вернёт '1 98 99 1 8 98 99 3 1 3 98 99 3'.

Пример практического использования списка TIntList (задача, сформулированная на DelphiKingdom в рубрике Головоломки, вопрос №58913). Дан массив слов. Необходимо построить из них цепочку, в которой каждое последующее слово начинается с той же буквы, на которую оканчивается предыдущее.

Идея алгоритма основана на последовательном включении в цепочку тех слов, которые отвечают критерию расстановки и ранее в цепочке не использовались.

function FindChain(a: array of String): boolean;
  var Need: boolean; n,i: Integer; t: TIntList;
// ------------------------------------------------

function Compare(a,b: String): boolean;
begin
  Result:= (Length(a)>0) and (Length(b)>0) and (a[Length(a)] = b[1]);

end;
// ------------------------------------------------
procedure Recurse(s: String; t: TIntList; k: Integer); // рекурсия
  var j,i: Integer; g: TIntList;
begin

  for j:= 0 to n-1 do
   if not Need then break else

   if Compare(a[t[t.Count-1]],a[j]) and (t.IndexOf(j) = -1) then
    begin
     i:= k+1; g:= t.AddList(j); Need:= i < n;
     if Need then Recurse(s+' '+a[j],g,i) else ShowMessage(s+' '+a[j]);
     g.Free;
   end;

end;
// ------------------------------------------------
begin
  Need:= true; n:= Length(a); Result:= n<2;
  if not Result then

    begin
      t:= TIntList.Create;
      for i:= 0 to n-1 do

       if Need then
        begin
          t.AssignInt(i);
          Recurse(a[i]+' ',t,1);
        end else break;
      t.Free;
     Result:= not Need;
    end;

end;

Следующий код

procedure TForm1.Button1Click(Sender: TObject);
var a: array of String;

begin
  SetLength(a,10);
  a[0]:= 'ствол'; a[1]:= 'канва'; a[2]:= 'лак'; a[3]:= 'коралл'; 
  a[4]:= 'перец'; a[5]:= 'ананас'; a[6]:= 'цветок'; a[7]:= 'ларец'; 
  a[8]:= 'лес'; a[9]:= 'сироп';
  if not FindChain(a) then ShowMessage('Нет цепочки слов.');
  a:= Nil;

end;

даст требуемую цепочку слов 'лак канва ананас ствол ларец цветок коралл лес сироп перец' (первая результативная перестановка 2150763894).

Если необходимо получить все цепочки, отвечающие условию задачи, то после незначительной модификации кода алгоритм покажет, что для данного примера из ровно 14 (последняя результативная перестановка 8946321507).

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 24.06.2009 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Delphi Professional Named User
Enterprise Connectors (1 Year term)
Rational ClearCase Multisite Floating User License
IBM RATIONAL Clearcase Floating User License + Sw Subscription & Support 12 Months
AutoCAD LT 2022 Commercial New Single-user ELD Annual Subscription
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Все о PHP и даже больше
Краткие описания программ и ссылки на них
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100