Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.08.2011, 15:51   #1
Silence255
 
Регистрация: 20.05.2011
Сообщений: 4
По умолчанию Динамический стек динамических очередей

Здравствуйте, товарищи программисты.
Я сейчас пытаюсь сделать курсовую, но чем дольше сижу - тем больше запутываюсь) Мало, что нашла именно по комбинированным структурам...
Задание может вам уже знакомо, в целом: динамический стек, каждый элемент которого является началом динамической очереди. Нужно все это делать через переменные-указатели и отдельные процедуры. Добавление элемента, как в основную (стек), так и во вспомогательную (очередь) структуры, поиск по всей структуре, удаление элемента из основной структуры (с удалением соответствующей ему очереди), удаление из вспомогательной, полный проход, т.е. вывод на экран всей структуры.
Задание вроде понятное, но все равно что-то не получается.
Делаю в Console Application.
Ниже описание используемых данных.

Код:
//описание вспомогательной структуры (очередь)
type
pSubQueue = ^TSubQueue;
   TSubQueue = record  //  описание структуры элементов очереди
   info: string;              //  информационное поле
   next: pSubQueue;     //  поле для адреса следующего элемента
end;
 
//описание основной структуры (стек)
type
PMainStack = ^TMainStack; 
  TMainStack = record    // описание структуры элементов стека
  inf: string;                  
  nextmain: pMainStack;
  FirstSub, LastSub: pSubQueue;    // конец и начало вспомогательной очереди
end;
 
var
 Sp,      //вершина стека
 PCurr, psub: PMainStack;   // текущий указатель в стеке
 PCurrSub: pSubQueue; // текущий указатель в очереди
 select: integer;     // выбор пункта меню
Меню выглядит так (пока так, чтоб понятно было):

Код:
begin
  repeat
        writeln('USER MENU:');
        writeln('1: Dobavlenie elementa v osnovnuyu strukturu (stack);');
        writeln('2: Dobavlenie elementa vo spomogatelnuyu strukturu (ochered);');
        writeln('3: Poisk zadannogo elementa;');
        writeln('4: Udalenie zadannogo elementa;');
        writeln('5: Prosmotr vsey struktury;');
        writeln('6: Udalenie vsey struktury;');
        writeln('7: Save & Exit');
        readln(select);
        case select of
            1: addone;
            2: addtwo;
    //        3: ...;
    //        4: ...;
            5: prosmotr;
    //        6: ...;
        end;
    until select = 7;
end.
А дальше проблемно...Вот добавление в стек:

Код:
procedure addone;
begin
  begin
 New(Pcurr);                 
 writeln('   ------->Enter element (string)');
 readln(Pcurr^.inf);
 writeln;
 Pcurr^.nextmain:=sp;
 sp:=Pcurr;         
  end;
end;
Тут вроде выполняется, добавляется...
Есть корявый проход с корявым выводом:

Код:
procedure prosmotr;
begin
 writeln;
 if sp<>nil then
  begin
   Pcurr:= sp;
   while pcurr<>nil do
    begin
     write(pcurr^.inf); 
     write('-->');
     pcurrSub:= pcurr^.firstSub;// тут пыталась сделать, чтоб вспомогательная очередь к элементу выводилась после стрелки 
     while pcurrSub<>nil do     
      begin
        write(pcurrSub^.info);
        pcurrSub:=pcurrSub^.next;
      end;
    pcurr:=pcurr^.nextMain;
    writeln;
    end;
    writeln;
  end
 else writeln('Stack pust!');
end;
Есть еще, тоже корявое подобие ввода элемента во вспомогательную очередь, но там по-моему вообще ужасть:

Код:
procedure addtwo;
begin
new(psub);
writeln('Vvedite osnovnoi element steka');//это чтобы знать в какую очередь добавлять
readln(psub.inf);
Pcurr:=sp;
while pcurr<>nil do
 begin
  if pcurr.inf=psub.inf then
   begin
   new(pcurrsub);
   writeln('vvedite novuy element (string)');
   readln(pcurrsub.info);
   pcurrsub^.next:=nil;
   pcurr.LastSub^.next:=pcurrsub; // вот это наверное бред, но я не знаю как тут правильно написать
   pcurr.LastSub:=pcurrsub;          //на этих двух строчках и прерывается добавление
   break;
   end;
  pcurr:= pcurr^.nextmain;
 end;
end;
В общем, если кому-то не очень сложно, подскажите. Поиск наверно после этих процедур несложно будет сделать, в удаление еще не вникала. Хотелось бы с этими разобраться, иначе про остальное и думать нечего. Надеюсь на отклики...
Silence255 вне форума Ответить с цитированием
Старый 27.08.2011, 17:19   #2
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

А почему вы решили, что "динамический" обязательно означает "связанный"?

Если пишете на Дельфи, ваша динамическая очередь проще реализуется через:

Код:
TQueueItem = record
  info: string;
  data: Integer;
end;

TQueue = array of TQueueItem;
В любом случае, поубирайте все эти Read/Write из кода. Представьте, что завтра ваш код будет использовать в GUI приложении. Будете всё заново переписывать?

Напишите универсальный код в отдельном модуле, которым захочет пользоваться кто-то ещё, кроме вас. А весь ввод\вывод вынесите в главную программу.

Например, добавление в очередь может выглядеть так:

Код:
procedure AddToQueue(Q: TQueue; const info: string; data: Integer);
var
  L: Integer;
begin
  L := Length(Q);
  SetLength(Q, L + 1);
  Q[L].info := info;
  Q[L].data := data;
end;
Ну или ваш код для связной очереди, в любом случае без ReadLn, а с передачей параметров.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 27.08.2011, 18:42   #3
Cannibal
Форумчанин
 
Регистрация: 17.02.2008
Сообщений: 191
По умолчанию

реализация очереди
Код:
unit mas;
interface
type
  Telem=char;

function maspush(elem : TElem): boolean;
function maspop (var elem : TElem) : boolean;

implementation
const n=100;
Type
  Tmass = array [0..n] of Telem;

var
  add : integer;
  rem : integer;
  mass : TMass;

function maspush(elem : TElem) : boolean;
begin
  inc(countPus);
  maspush:=false;
  if (add-rem) = -1 then
    Inc(cpolon)
  else begin
    mass[add] := elem;
    add := (add+1) mod n;
    maspush := true;
  end;
  if add > rem then
    SredPros := SredPros + n-(abs(rem-add))
  else
    SredPros := SredPros + (rem - add);
end;

function maspop (var elem : TElem) : boolean;
begin
  inc(countPop);
  maspop := false;
  if (add = rem) then
    inc(cpust)
  else begin
    elem := mass [rem];
    rem := (rem+1) mod (n+1);
    maspop := true;
  end;
  if add > rem then
    SredPros := SredPros + n-(abs(rem-add))
  else
    SredPros := SredPros + (rem - add);
end;

begin
  Cpust := 0;
  cpolon := 0;
  add:=0;
  rem:=0;
end.
реализация стека
Код:
unit stak2;
interface
type
  TElem=char;
procedure push (elem:TElem);
procedure pop;
function Ispolon:boolean;
function IsPust:boolean;
function upElem:TElem;

implementation
const maxint=1000;

var stak:array[0..maxint]of Telem;
  top:integer;
  
procedure push(elem:TElem);
begin
  if IsPolon then begin
    writeln('Error: стек, в который вы пытаетись добавить значение полон');
    halt
    end
  else begin
     inc(top);
     stak[top]:=elem;
  end;
end;

procedure pop;
begin
  if isPust then begin
    writeln('Error: стек, из которого вы пытаетесь извлечь значение пуст');
    halt;
    end
  else
    dec(top);
end;

function IsPolon:boolean;
begin
  IsPolon:=top=maxint;
end;

function isPust:boolean;
begin
  isPust:=top=0;
end;

function upElem:TElem;
begin
  if ispust then
    upelem:='#'
  else
    upElem:=stak[top];
end;

begin
  top:=0;
end.
думаю разберешься, как их связать
Mathematicians often mix up Christmas and Halloween, because Dec.25=Oct.31.
Cannibal вне форума Ответить с цитированием
Старый 29.08.2011, 13:57   #4
Silence255
 
Регистрация: 20.05.2011
Сообщений: 4
По умолчанию

Цитата:
Сообщение от veniside Посмотреть сообщение
А почему вы решили, что "динамический" обязательно означает "связанный"?

Если пишете на Дельфи, ваша динамическая очередь проще реализуется через:

Код:
TQueueItem = record
  info: string;
  data: Integer;
end;

TQueue = array of TQueueItem;
Ну или ваш код для связной очереди, в любом случае без ReadLn, а с передачей параметров.
Это, например, так? Добавление в основной стек:
Код:
procedure addone(var sp1:pMainStack;inf:string);
var
tmp:pMainStack;
begin
 New(tmp);               
 tmp^.nextmain:=sp1;
 tmp^.inf:=inf;
 sp1:=tmp;
end;
Silence255 вне форума Ответить с цитированием
Старый 29.08.2011, 15:12   #5
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

Да, так намного лучше. Я бы ещё переименовал Add в Push, а Delete в Pop, будет более понятно, что у нас стек, а не просто связанный список.

В принципе, если предполагается только 1 стек в программе, его можно не передавать в каждую процедуру, а сделать глобальной переменной. (В обычной программе, а не курсовой, я бы вобще посоветовал сделать из него класс, стройность и читаемость кода улучшается на порядок).
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Программная реализация динамического списка динамических очередей Ghost1k Помощь студентам 2 30.08.2011 22:41
динамический стек klentan Помощь студентам 0 01.06.2011 19:40
динамический стек. удаление элемента alex(21) Помощь студентам 2 01.11.2010 20:22