Конференция "Прочее" » однонаправленные списки [D7, XP]
 
  • Nostalgia © (19.12.08 21:56) [0]
    Здравствуйте! подскажите как сделать данное задание. Дан список В, который состоит из записей: первое поле - слова из 10 литер, второе - адрес следующего элемента. нужно составить программу для удаления последнего элемента списка.
  • palva © (19.12.08 22:13) [1]
    А у последнего элемента какой адрес следующего элемента?
    Если ноль, то задача решается просто. Нужно дойти до предпоследнего элемента и обнулить в нем адрес следующего элемента.
    (Обнулить адрес значит записать в него nil)
  • Nostalgia © (19.12.08 22:22) [2]
    да, ноль. но дело в том, что я не знаю как это правильно записать и вообще с чего начать...
  • Сергей М. © (19.12.08 22:30) [3]
    А Паскаль-то знаешь ?
  • Nostalgia © (19.12.08 22:34) [4]
    delphi(object pascal) знаю немного...я на первом курсе
  • {RASkov} © (19.12.08 22:37) [5]
    > нужно составить программу для удаления последнего элемента списка.

    Да тут одна строчка кода видимо.... В чем гвоздь?
  • Nostalgia © (19.12.08 22:39) [6]
    я вообще не знаю какие переменные обьявлять и как работать с указателями
  • Сергей М. © (19.12.08 22:42) [7]

    > знаю немного


    Т.е. функцию или процедуру объявить в состоянии ?
    Тогда начни с объявления процедуры, принимающей параметром указатель на первую запись списка..
  • Nostalgia © (19.12.08 22:46) [8]
    program Project2;
    {$APPTYPE CONSOLE}
    uses
     SysUtils;
    type spB=^elem;
        elem=record
        info:string;
        next:spB;
        end;
    var beg,p:spB;

    begin
    beg:=p;

     { TODO -oUser -cConsole Main : Insert code here }
    end.                    // вот я уже начинала...но что делать дальше не знаю
  • Сергей М. © (19.12.08 22:47) [9]

    > какие переменные обьявлять


    Можно никакие не объявлять, в задании это явно не требуется.
    Но как минимум один указательный тип объявить безусловно нужно - параметр твоей процедуры будет именно этого типа.
  • Сергей М. © (19.12.08 22:54) [10]
    Cейчас ты идешь сюда

    http://pascal.helpov.net/index/dynamic_lists_pascal_programming

    внимательно изучаешь материал с картинками, по образу и подобию (но с коррективами в соответствии с твоим заданием) делаешь заготовку своей программы, пробуешь ее, и если после этого возникнут конкретные вопросы, задаешь их здесь.
  • Denis__ © (20.12.08 13:56) [11]
    Вирта читать. Ахо, Ульмана, Кормена. До полного просветления.
  • Тын-Дын © (20.12.08 13:58) [12]
    Удалено модератором
    Примечание: Не хами
  • Johnmen © (20.12.08 14:19) [13]

    > Тын-Дын ©   (20.12.08 13:58) [12]
    > Просветлённый такой, аж жуть берёт.

    Да ты не бойся, ты поможи, чем можешь самим неместным, извинив, что они обращаются...
  • KSergey © (20.12.08 14:26) [14]
    Эта, в задании не сказано на куда указывает указатель из последнего элемента. Или сие надо додумать?

    Чтобы начать делать - надо как-то придумать как это все хранится... Я бы начал с этого, чтобы было на чем тестировать основной код.
    Опять же про new почитать здорово.
    И string - это ни разу не "слово из 10 литер".
  • TUser © (20.12.08 14:35) [15]
    Давай начнем:

    0. Тебе надо удалять последний элемент списка. Это будет делать какая-то часть твоей программы, достаточно автономная от остальных частей. В паскале такая часть программы называется "процедура" (procedure).

    1. Теперь тебе надо написать эту процедуру. Синтаксис погляди в любом учебнике, я тут не по паскалю, а по трындению, так что звиняй. Вообщем, наверное у этой процедуры будет название, ну и какие-то параметры. Ведь должна де процедура получать извне сведения о том, с каким списком ей работать, например.

    2. Итак, у нас есть процедура, которая объявлена и получает в качестве параметра указатель на первый элемент списка. Тебе надо найти последний. Но это не трудно. Действительно, в первом элементе списка хранится указание на второй, в нем на третий и т.д. Надо пройтись по этой цепочке.

    3. Что мы понимаем под словами "надо пройтись"? Это означет, конечно, не шагать в кирзе по гигабайтным кингстонам, или какая у тебя там память. В программизме это значит, что надо завести некоторое место в памяти, где будет хранится указатель на элемент списка. Такое место называется "переменная" (в паскале используется уменьшительно-ласкательное var).

    4. Вот значит, основной цикл нашей процедуры будет устроен так: есть переменная, назовем ее У1. Вначале там хранится адрес первого элемента сиписка. И потом каждый раз мы выбираем из этого первого элемента указатель на следующий, и присваиваем этот указатель переменной У1.

    5. А когда наш циел должен закончиться? (Ну, нельзя же циклиться бесконечно!) Тут решение простое - когда мы дошли до конца. Когда в У1 оказался нуль, указатель вникуда, или как пишут пасквилянты nil.

    6. Теперь надо бы сделать вот что - удалить последний элемент. Айайай. мы его забыли, каждый раз затирая в У1 значение, и заменяя его новым. Ну не беда. всегда можно выдумать еще одну переменную - У2, в которой будем запоминать значение преддущего элемента.

    7. Тогда основной цикл будет выглядить так: запомнить в У2 то, что сейчас содержится в У1 и в У1 написать указатель на следующий элемент (содержится в той записи, на которую указывает У1).

    8. Ура. Теперь после прохождения всего цикла можно удалять У1. Диспозиционировать. если по-пасквилянстски. На это есть специальная процедура, освобождающая память.

    9. Все. Можно пить шампанское. Но сначала надо прибрать за собой. В предпоследнем элементе списка содержится указатель на уничтоженный элемент. Беда. Но не большая. Надо туда записать "вникуда" (nil).

    10. А для этого предпоследний элемент надо запомнить. Мы уже делали что-то подобное, заведя переменную У2. Заведем себе еще и У3, и будет наш цикл на каждой итерации записывать значение из У2 в У3, из У1 в У2, а в У1 - новое значение.

    11. После выполнения цикла (в У1 попало "вникуда") мы диспознем У2, а в У2 запишем "никуда" в качестве указателя на следующий элемент (тем самым предпоследний элемент станет последним).

    12. Если мы все это переведем на паскаль и покажем преподу, то он нам поставит банан, и будет прав. Только такая обезъяна как я могла забыть, что бывают списки ну совсем коротенькие, допустим из одного элеента. Так что после цикла надо предусмотреть эти особенности. Пусть это будет самостоятельным творческим решением, и останется в моем трактате только 12 пунктов, а то 13 - несчастливое число.

    Вообщем, приерно такова была бы моя логика по пунктам, если бы я вздемал писать такую процедуру.
  • Тын-Дын © (20.12.08 16:19) [16]
    Удалено модератором
    Примечание: Не хами
  • Denis__ © (20.12.08 16:31) [17]

    > Просветлённый такой, аж жуть берёт.

    Вам что-то не нравится? Нафиг было код давать? TUser же нормально, по пунктам рассказал , что делать. А теперь будет копи-паст.
  • Тын-Дын © (20.12.08 16:59) [18]

    > Denis__ ©   (20.12.08 16:31) [17]
    > > Просветлённый такой, аж жуть берёт.Вам что-то не нравится?
    >  Нафиг было код давать? TUser же нормально, по пунктам рассказал
    > , что делать. А теперь будет копи-паст.


    Хамство не нравится. Вот в потрепаловке уже сказали, что направление задают модераторы. Так и есть.

    А код путь будет копи-паст. Жалко?

    unit Unit1;

    interface

    uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, StdCtrls;

    type

     PElement=^TElement;
     TElement=record
       info: string[10];
       next: PElement;
     end;

     TForm1 = class(TForm)
       Button1: TButton;
       Button2: TButton;
       procedure Button1Click(Sender: TObject);
       procedure Button2Click(Sender: TObject);
     private
       { Private declarations }
     public
       { Public declarations }
     end;

    var
     Form1: TForm1;
     RootElement: PElement;

    implementation

    {$R *.dfm}

    procedure AddElement(p: PElement);
    var
     pCurrElement: PElement;
    begin
     if RootElement=nil then
     begin
       RootElement := p;
       p^.next := nil;
       Exit;
     end;
     pCurrElement := RootElement;
     while pCurrElement^.next<>nil do pCurrElement := pCurrElement^.next;
     pCurrElement^.next := p;
     p^.next := nil;
    end;

    function DeleteLastElement: PElement;
    var
     pCurrElement: PElement;
    begin
     Result := nil;
     if RootElement=nil then Exit;
     if RootElement^.next=nil then
     begin
       Dispose(RootElement);
       RootElement := nil;
       Exit;
     end;

     pCurrElement := RootElement;

     while pCurrElement^.next^.next<>nil do pCurrElement := pCurrElement^.next;
     Dispose(pCurrElement^.next);
     pCurrElement^.next := nil;
     Result := pCurrElement;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var
     i: Integer;
     p: PElement;
    begin
     for i := 0 to 100000 do
     begin
       New(p);
       p^.info := IntToStr(i);
       AddElement(p);
     end;
    end;

    procedure TForm1.Button2Click(Sender: TObject);
    begin
     while DeleteLastElement<>nil do ;
    end;

    end.

  • Leonid Troyanovsky © (20.12.08 17:09) [19]

    > Тын-Дын ©   (20.12.08 16:59) [18]

    > А код путь будет копи-паст. Жалко?

    А где dfm & dpr? Что за жлобство.

    --
    Regards, LVT.
  • Denis__ © (20.12.08 17:16) [20]

    > Тын-Дын ©   (20.12.08 16:59) [18]
    >А код путь будет копи- паст. Жалко?


    Жалко. Пока сам не напишешь, САМ, понимаешь, с нуля! Не поймешь. А скопипастить, даже разобрать - не то это. Повторить скопи-пастеное довольно трудно. А написать отличающееся буквально парой строк - вообще засада.
  • Тын-Дын © (20.12.08 17:16) [21]
    Удалено модератором
  • Тын-Дын © (20.12.08 17:17) [22]

    > Denis__ ©   (20.12.08 17:16) [20]
    > > Тын-Дын ©   (20.12.08 16:59) [18] >А код путь будет копи-
    >  паст. Жалко? Жалко. Пока сам не напишешь, САМ, понимаешь,
    >  с нуля! Не поймешь. А скопипастить, даже разобрать - не
    > то это. Повторить скопи-пастеное довольно трудно. А написать
    > отличающееся буквально парой строк - вообще засада.


    Вот когда появится хоть какой-то опыт, тогда и разберётся.
  • Тын-Дын © (20.12.08 17:18) [23]
    Да и не жалко мне. Небольшая разминка для мозгов не повредит.
    10-15 минут развлечения по написанию кода - полезно иногда.
  • Denis__ © (20.12.08 17:19) [24]

    > Вот когда появится хоть какой-то опыт, тогда и разберётся.

    Сначала опыт, потом знания? Оригинально!
  • Denis__ © (20.12.08 17:20) [25]
    ТЕБЕ не повредит. А тому, кто просил?
  • Тын-Дын © (20.12.08 17:24) [26]

    > Denis__ ©   (20.12.08 17:20) [25]
    > ТЕБЕ не повредит. А тому, кто просил?


    Здесь не курсы по обучению.
    Каждый может попрость и код дать, и совет.
    Так же точно и ответить могут. Кто написать конкретный код, а кто совет дать.
    Абсолютно неважно.
    Не стоит считать себя учителем.
  • Leonid Troyanovsky © (20.12.08 17:32) [27]

    > Denis__ ©   (20.12.08 17:20) [25]

    > ТЕБЕ не повредит. А тому, кто просил?

    Эх, Денис. Тут уж ничего никому не повредит.
    А код  - пусть уж будет, мало ли его в инете.
    И не факт, что его прочитают или применят.

    Кста, на наши тусовки и преподы заходят :)

    --
    Regards, LVT.
  • Denis__ © (20.12.08 17:43) [28]

    > Не стоит считать себя учителем.

    Гыыыы)))) Да я и не считаю. Просто мне кажись, мозги начали вправлять в универе. Да и тут тоже, спасибо отдельным людям.


    > Leonid Troyanovsky ©   (20.12.08 17:32) [27]

    > Эх, Денис. Тут уж ничего никому не повредит.А код  - пусть
    > уж будет, мало ли его в инете.И не факт, что его прочитают
    > или применят.Кста, на наши тусовки и преподы заходят :)

    Поиск в инете - тоже обучение)) Помню, год-два назад я тут тоже код выпрашивал. и на ДК. и на исходниках)) Каюсь. Списки и др. динамические недавно только понял. Почитал, кстати Вирта и т.д. А главное - самому писать.
  • Тын-Дын © (20.12.08 18:00) [29]

    > Denis__ ©   (20.12.08 17:43) [28]


    Ты исходишь немного не из тех предпосылок по поводу кода в инете.
    Подумай на досуге - почему авторы книг в своих текстах не только приводят готовый рабочий код, но и прикладывают диски с исходниками?
    Ведь оттуда ещё проще скопировать код - и искать не надо.

    На самом деле значительно проще изучать готовый исходник. С этого и начинается в большинстве случаев обучение. После просмотра, изучения кода, попыток написания собственного, и начинается уже собственно учёба.
  • Leonid Troyanovsky © (20.12.08 18:22) [30]

    > Тын-Дын ©   (20.12.08 18:00) [29]

    >  С этого и начинается в большинстве случаев обучение. После
    > просмотра, изучения кода, попыток написания собственного,
    >  и начинается уже собственно учёба.

    В большинстве случаев - белые начинают и заканчивают.
    Ну, а, собс-но, учеба никогда не заканчивается.

    --
    Regards, LVT.
  • app © (20.12.08 20:49) [31]
    > Leonid Troyanovsky  (20.12.2008 18:22:30)  [30]

    Давайте с вопросами давать код или нет в Прочее.
  • antonn © (20.12.08 22:00) [32]

    > Давайте с вопросами давать код или нет в Прочее.

    Давайте сами участники будут сами решать, дать код или нет.
    Это все таки форум.
  • {RASkov} © (20.12.08 22:12) [33]
    Весело у вас тут :)
    Nostalgia наверное в шоке)
  • Anatoly Podgoretsky © (20.12.08 22:14) [34]

    > antonn ©   (20.12.08 22:00) [32]

    Они и решают, а вот обсуждение данного вопроса решают модераторы.
  • Nostalgia © (20.12.08 22:47) [35]
    мдя....не то слово в шоке...
  • Nostalgia © (20.12.08 22:53) [36]
    а почему код такой большой?? просто препад говорил , что он должен быть буквально в пару строк...
  • Тын-Дын © (20.12.08 23:00) [37]

    > Nostalgia ©   (20.12.08 22:53) [36]
    > а почему код такой большой?? просто препад говорил , что
    > он должен быть буквально в пару строк...


    А тут и написана пара строк.

    function DeleteLastElement: PElement;
    var
    pCurrElement: PElement;
    begin
    Result := nil;
    if RootElement=nil then Exit;
    if RootElement^.next=nil then
    begin
      Dispose(RootElement);
      RootElement := nil;
      Exit;
    end;

  • Тын-Дын © (20.12.08 23:02) [38]
    pCurrElement := RootElement;

    while pCurrElement^.next^.next<>nil do pCurrElement := pCurrElement^.next;
    Dispose(pCurrElement^.next);
    pCurrElement^.next := nil;
    Result := pCurrElement;
    end;

  • Nostalgia © (20.12.08 23:05) [39]
    вряд ли этот код пойдёт.....мне лабораторную работу сдавать.......и обьяснять. классы например мы пока не проходили. код написала ещё вчера... но не понимаю, что нужно вводить и выводить.точнее знаю.....не знаю как правильно оформить. подскажите если не сложно. вот код:
    program lab26_z3_odn_spiski;

    {$APPTYPE CONSOLE}

    uses
     SysUtils;
    type spB=^elem;
        elem=record
        info:string;
        next:spB;
        end;
    var x,u,dx:spB;
    begin
    x:=u;
    dx:=u;
    while x^.next<>nil do
    begin
    dx:=x;
    x:=x^.next;
    end;
    dx^.next:=nil;
    dispose (x);
     { TODO -oUser -cConsole Main : Insert code here }
    end.
  • Palladin © (20.12.08 23:08) [40]
    хм... такого я не предполагал... что аж в прочее :) отлично помогли. закрепили делом перестройку. :)
  • Anatoly Podgoretsky © (20.12.08 23:11) [41]

    > x:=u;
    > dx:=u;

    u не инициализирован, но дальше идет попытка его использования.
    Поскольку это глобальная переменная, то начальное значение nil
    и while x^.next<>nil doдолжно вызвать AV поскольку nil.next
  • Nostalgia © (20.12.08 23:13) [42]
    обьясните попроще...
 
Конференция "Прочее" » однонаправленные списки [D7, XP]
Есть новые Нет новых   [134449   +17][b:0][p:0.002]