1

Тема: Кільцевий список

Усім доброго дня! Будь ласка, допоможіть мені з такою задачою:
Описати клас КІЛЬЦЕВИЙ СПИСОК з довільних об'єктів та реалізувати дії над списками
1) Почати роботу
2) Довжина списку
3) Перейти до наступного елемента
4) Поточний елемент
5) Вставити елемент
6) Видалити елемент
Описати клас ЕЛЕМЕНТ на базі початкового об'єкта, який має методи "показати" та "дорівнює", та розв'язати задачу обчислення максимальної кількості рівних елементів списку, що йдуть підряд.
Розв'язати задачу для елементів, які містять масиви заданого розміру.

Ось, власне, реалізація кільцевого списку. Операції Init, Next та Current написала сама, тому до кінця не впевнена в їх правильності.

unit IntRList;

interface

type
  rlist = ^relem;
  relem = record
            d: integer;
            next: rlist
          end;

procedure Init(var r: rlist);
function Len(r: rlist): integer;
procedure Next(var r: rlist);
function Current(r: rlist): integer;
procedure Insert(var r: rlist; n: integer);
procedure Delete(var r: rlist);

implementation

procedure Init(var r: rlist);
  begin
    r:=nil
  end;

function Len;
  var i: word;
      p: rlist;
  begin
    i:=0; p:=r;
    if p<>nil then
      repeat
        p:=p^.next;
        i:=i+1
      until p=r;
    Len:=i
  end;

procedure Next(var r: rlist);
  begin
   if r<>nil then begin
     r:=r^.next;  end
   else
     begin
      writeln('Next: Spysok porozhniy');
      halt
     end;
  end;

function Current(r: rlist): integer;
  begin
   if r<>nil then begin
     Current:=r^.d; end
   else
     begin
      writeln('Current: Spysok porozhniy');
      halt;
      Current:=0;
     end;
  end;

procedure Insert;
  var p: rlist;
  begin
    new(p);
    if r=nil then
      begin
        p^.d:=n; p^.next:=p;
      end
    else
      begin
        p^:=r^; r^.d:=n; r^.next:=p;
      end;
    r:=p;
  end;

procedure Delete;
  var p: rlist;
  begin
    if r=nil then begin
      writeln('Delete: Spysok porozhniy');
      halt
    end;
    if r^.next=r then
      begin
        p:=r; r:=nil
      end
    else
      begin
        p:=r^.next; r^:=p^
      end;
    dispose(p)
  end;
 
end.

А ось мої намагання розв'язати задачу. Як я зрозуміла умову задачі, то мені треба створити порожній список,  ввести "l" масивів розміру "size", та вставити їх по черзі в список. А потім, вважаючи ці масиви елементами списку, просто порівнювати їх. І у разі рівності збільшувати макс. значення рівних елементів sum на одиничку.

Program Proekt2;

Uses IntRList;

Type
  AnyRef = ^AnyObject;
  AnyObject = Object
                Constructor Initial;
                Destructor Done; Virtual;
              end;
  ElemRef = ^Element;
  Element = Object(AnyObject)
             public
              Procedure Show(s: rlist);
                begin
                 writeln(s);
                end;
              Function Equals(s,s1: rlist): boolean;
                begin
                 if s=s1 then
                  begin
                   Equals:=true;
                  end
                 else
                  begin
                   Equals:=false;
                  end;
                end;
            end;
  Constructor AnyObject.Initial;
    begin
    end;
  Constructor AnyObject.Done;
    begin
    end;


var m: array [1..size] of integer;
    l,k,i,sum: integer;
    spysok: rlist;

begin
 Init(spysok);

 write('Rozmir massyviv = ');
 read(size);

 write('Dovzhyna spysku = ');
 read(l);

 for k:=1 to l do
  begin
   for i:=1 to size do
    begin
     readln(m[i]);
    end;
   Insert(m,k);
   k:=k+1;
   end;

 sum:=0;
 if m=m^.next then
  begin
   sum:=sum+1;
  end;

end.

Відкомпілювати програму не вдається (помилка 37, пропущено End а де - не знаю)

Буду дуже вдячна за ваш час і вашу допомогу. Якщо у вас будуть якісь запитання, постараюсь на них відповісти)

2

Re: Кільцевий список

v.pro
У вас зараз в елементі списку зберігається "d: integer", а має бути "obj: AnyRef". Тому AnyObject краще винести в окремий модуль, який підключити до IntRList та Proekt2.
Крім того, клас Element повинен містити поле типу масив, щось на зразок "mas: array[1..n] of integer". А методи цього класу мають приймати на вхід цей самий Element. Навіть не так... Один тільки Equals має приймати на вхід один Element. А Show не повинен мати параметрів, і повинен звертатися до власного поля mas.
Загублений End я не шукав. Як перепишете код, пошукаєте самі.

Подякували: v.pro1

3 Востаннє редагувалося v.pro (22.12.2013 14:46:28)

Re: Кільцевий список

Дякую за оперативну відповідь) Знайшла окремий модуль (сподіваюсь, той, що треба) для AnyObject:

Unit AnyThing;
 
interface
 
Type
  AnyRef = ^AnyObject;
  AnyObject = Object                       
                Constructor Init;          
                Destructor Done; Virtual; 
              end;
 
implementation
 
  Constructor AnyObject.Init;
    begin end;
 
  Destructor AnyObject.Done;
    begin end;
 
end.

А от щодо методів трішки не зрозуміла. Чи Equals взагалі не так повинна бути реалізована?

Program Proekt2;

Uses IntRList, AnyThing;

const n:=5;

Type
  ElemRef = ^Element;
  Element = Object(AnyObject)
             private
              mas: array [1..5] of integer;
             public
              Procedure Show;
                begin
                 writeln(mas);
                end;
              Function Equals(Element: rlist): boolean;
                begin
                 if Element=Element^.next then
                  begin
                   Equals:=true;
                  end
                 else
                  begin
                   Equals:=false;
                  end;
                end;
            end;...........................................

4

Re: Кільцевий список

1. Вказуйте компілятор. В різних реалізаціях Object Pascal бувають досить суттєві відмінності.
2. В Object Pascal поняття "довільний об'єкт" визначено однозначно, це тип Object. А посилання на об'єкти заборонені, оскільки самі об'єктні типи вже є посиланнями.
Таким чином, опис елемента списку має бути десь таким:

type
  CycleListElement = Object
            value: Object;
            next: CycleListElement;
            constructor Init(o: Object);
            function Length: integer;
            procedure Next;
            function Current: Object;
            procedure Insert(o: Object);
            function Delete(o: Object): boolean;
            function Delete(count: integer):boolean; override;
          end; 

А далі (можливо, в іншому модулі) треба успадкувати базовий тип CycleListElement і створити

type
    Element = Object(CycleListElement)
      A: Array[1..10] of integer;
      procedure Show;
      function Equals(e: Element): boolean;
    end;
Подякували: v.pro1

5

Re: Кільцевий список

Перепрошую, що відразу не написала. Borland Pascal 7.1

6

Re: Кільцевий список

v.pro написав:

Чи Equals взагалі не так повинна бути реалізована?

Метод Equals повинен порівнювати власний mas із mas-ом того об’єкта, який йому передали у якості параметра.

koala
Слушне зауваження. У завданні дійсно йдеться про "клас КІЛЬЦЕВИЙ СПИСОК".

Подякували: koala, v.pro2

7

Re: Кільцевий список

Koala, Torbins, дякую за зауваження) Спробую цим скористатися

8

Re: Кільцевий список

Доброго вечора!
Описала елементи (нарешті відкомпілювалося)
Але знову виникла проблема( Не можу зрозуміти, як можна вставити масив чисел в список (як один елемент) Чи може треба створювати щось типу конструктора CreateMas? Бо з Insert нічого не виходить... Допоможіть, будь ласка, дайте може підказку яку, бо вже руки опускаються робить її, лабу чортову

Поточний код:

Program Lab2;

const q=3;

type
  AnyObject = Object
                public
                  Constructor Init;
                  Destructor Done;
              end;

  Constructor AnyObject.Init;
    begin
    end;
  Destructor AnyObject.Done;
    begin
    end;

type

  rlist = ^relem;
  relem = record
            d: integer;
            next: rlist
          end;

type

  List = Object(AnyObject)
           r: rlist;
           public
             Constructor RLInit;
             Function Len: integer;
             Procedure Next;
             Function Current: integer;
             Procedure Insert;
             Procedure Delete;
             Destructor RLDone;
         end;

  Constructor List.RLInit;
    begin
      r:=nil
    end;

  Function List.Len: integer;
    var i: word;
        p: rlist;
    begin
      i:=0;
      p:=r;
      if p<>nil then
        repeat
          p:=p^.next;
          i:=i+1
        until p=r;
      Len:=i
    end;

  Procedure List.Next;
    begin
      if r<>nil then
        begin
          r:=r^.next;
        end
      else
        begin
          writeln('Next: Spysok porozhniy');
          halt
        end;
    end;

  Function List.Current: integer;
    begin
      if r<>nil then
        begin
          Current:=r^.d;
        end
      else
        begin
          writeln('Current: Spysok porozhniy');
          halt;
          Current:=0;
        end;
    end;

  Procedure List.Insert;
    var p: rlist;
        n: integer;
    begin
      new(p);
      if r=nil then
        begin
          p^.d:=n;
          p^.next:=p;
        end
      else
        begin
          p^:=r^;
          r^.d:=n;
          r^.next:=p;
        end;
      r:=p;
    end;

  Procedure List.Delete;
    var p: rlist;
    begin
      if r=nil then
        begin
          writeln('Delete: Spysok porozhniy');
          halt
        end;
      if r^.next=r then
        begin
          p:=r;
          r:=nil
        end
      else
        begin
          p:=r^.next;
          r^:=p^
        end;
      dispose(p)
    end;

  Destructor List.RLDone;
    var p,p1: rlist;
        n: integer;
    begin
      p:=r;
      while p<>nil do
        begin
          n:=p^.d;
          p1:=p;
          p:=p^.next;
          dispose(p1);
        end;
        r:=nil;
    end;

type M = array [1..q] of integer;

type

  Element = Object(AnyObject)
              mas: M;
              public
                Constructor ElemInit;
                Procedure Show;
                Function Equals: boolean;
                Destructor ElemDone;
            end;

  Constructor Element.ElemInit;
    var mas1: M;
    begin
      mas:=mas1;
    end;

  Procedure Element.Show;
    var j: integer;
    begin
      for j:=1 to q do
        begin
          write(mas[j]);
        end;
    end;

  Function Element.Equals: boolean;
    var mas1: M;
    h: integer;
    begin
      for h:=1 to q do
        begin
          if mas[h]=mas1[h] then
            begin
              Equals:=true;
            end
          else
            begin
              Equals:=false;
            end;
        end;
    end;

  Destructor Element.ElemDone;
    begin
    end;

{-----------------------------------------------------------------------}

var msv: M;
    sp,sp1: List;
    k,l,s: integer;
begin
  sp.RLInit;
  sp1.RLInit;
  write('Vvedit dovzhynu spysku = ');
  read(l);
  for k:=1 to l do
    begin
      write('Vvedit massyv ',k, '=');
      for s:=1 to q do
        begin
          read(msv[s]);
        end;
      msv.Insert;



          end;
          end.

9 Востаннє редагувалося koala (24.12.2013 19:50:42)

Re: Кільцевий список

Не змішуйте об'єкти і вказівники. Змінні об'єктного типу, насправді, вже є вказівниками.

Подякували: v.pro1

10

Re: Кільцевий список

v.pro
Іще раз повторю, що зараз у вас в елементі списку зберігається "d: integer", а має бути "obj: AnyRef" (до речі куди він подівся?) Відповідно і List.Insert має мати параметр такого ж типу, й інші методи класу List також трохи зміняться.
Далі у циклі "for k:=1 to l do" ви створюєте по одному об’єкту класу Element (нехай буде elem), заповнюєте його mas, та пхаєте його у список: "msv.Insert(elem)".
Ну й плюс Element.Equals мав би бути "Function Element.Equals(elem: Element): boolean;" або "Function Element.Equals(AMas: M): boolean;".


koala написав:

Не змішуйте об'єкти і вказівники. Змінні об'єктного типу, насправді, вже є вказівниками.

Старі об’єкти не завжди є вказівниками, за певних обставин вони й у стеку можуть лежати. А от у Делфі нові об’єкти дійсно завжди є вказівниками.

Подякували: v.pro1

11

Re: Кільцевий список

v.pro написав:

Зробила так, як ви написали (замінила d: integer на obj: AnyRef)
Але не можу зрозуміти, що ви мали на увазі під створенням об'єкту класу Елемент і заповнення його mas. Тобто треба додатково створити конструктор Create чи просто присвоїти elem:=...? Але як потім заповнити його масивом - поелементно вставляти туди [s ]-ті члени чи спочатку зчитати масив, і потім якось присвоїти mas:=...

У старому паскалі об’єкти створюються так, якщо не помиляюсь:

type
  ElemRef = ^Element;

var
  elem: ElemRef;
//...
New(elem);
//ну а далі
elem.mas := 

12

Re: Кільцевий список

Ура! Нарешті запрацювало) Дуже дякую за допомогу! З наступаючими святами і всіх благ))

Подякували: koala1

13

Re: Кільцевий список

Робочий код можете сюди викласти, для майбутніх поколінь?

Подякували: Torbins1