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

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

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

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 11.11.2009, 13:05   #1
diliana
Форумчанин
 
Аватар для diliana
 
Регистрация: 24.05.2009
Сообщений: 119
Вопрос Массив указателей (паскаль)

Всем привет!

задание такое - создать массив из динам-х очередй со всеми типовыми опеерациями для данной струк-ры
Это все я представляю так - создается некий массив, элементами которого должны быть собственно очереди, а очереди заполняются нашими данными (например с типом integer)

Я решила, что данную струк-ру можно реализовать с помощью массива указателей...
Я описала структуру и операции с очередью (дабавление, просмотр, удаление), но я не могу разобраться как работать с таким массивом, т.е.
как добавить новый элемент (очередь) в такой массив ???
как сделать просмотр этого массива ???
как удалить элемент из такого массива ???

Прошу вашей помощи.... Пожалуста помогите разобраться....

Вот мое описание структуры

Код:
program Project_MQ_3;

{описание структуры}
const
  N = 100;
Type
{очередь}
  pQueue = ^TQueue;{ссылочный тип}
  TQueue = record 
    data : integer; {данные}
    next : pQueue;
    end;

{массив указателей}
  TMassQu = array [1..N] of pQueue;

var
  key: byte;
  Head, Last: pQueue;{указатели начала и конца очереди}
  mass: TMassQu;
  x: integer;

вот процедуры для очереди


Код:
{===операции с очередью====}
{добавление элемента в очередь}
Procedure AddQ(var HeadT, LastT: pQueue);
var
  temp: pQueue;
  x: integer;
begin
  Randomize;
  x := 1+random (100);
  New (temp);
  temp^.data := x;
  temp^.next := nil;
  If HeadT = nil then HeadT := temp
   else LastT^.next := temp;
  LastT := temp;
  write(' : ', temp^.data, '  ->  dobavlen!');
  Writeln;
END;

{просмотр элементов в очереди}
Procedure ScanQ(var HeadT: pQueue);
var
  temp: pqueue;
begin
  if HeadT = nil then writeln('Net elementov ')
  else
  begin
    temp := HeadT;
    while temp <> nil do
      begin {проход по очереди до конца}
       write(temp^.data, ' ');{вывод всех элементов очереди}
       temp := temp^.next;
      end;
  end;
end;

а вот операции с массивом, то что пока сама смогла сделать...

Код:
{===операции с массивом=====}

{добавление очереди в массив}
Procedure AddMasQ(var mass: TMassQu; var x: integer);
var
  i, j, x_que, x_elem, k : integer;
  temp, HeadT, LastT: pQueue;
begin
  {вводим число элементов (очередей)  массива }
  write ('Vvesti chislo elementov massiva : ');
  readln (x_que);
  k:=0;
  For i := 1 To x_que Do
   begin
     New (temp);// выделить память для новой очереди
     mass [i] := temp;// включение в массив ссылки адреса очереди
     HeadT := nil; LastT := nil;{создаем пустую очередь}
     Inc (k);// считаем очереди
     writeln(' * New ochered # : ', k);
     write(' * Vvesti chislo elementov ocheredi: ');
     readln(x_elem);
     for j := 1 to x_elem do
        begin
         write('    element # ', j);
         AddQ(HeadT, LastT);{заполняем очередь элементами}
        end;
   writeln;
 end;
end;

{просмотр массива}
Procedure ScanMasQ(var mass: TMassQu; var x: integer);
var
  i, j,x_que, x_elem, k: integer;
  HeadT: pQueue;
begin
  writeln ('Prosmotr massiva');

end;

Код:

{меню программы}
BEGIN
 Repeat
  Writeln ('==========================================');
  Writeln ('Program MQ');
  Writeln ('==========================================');
  Writeln ('1:  Dobavit ochered v massiv');
  Writeln ('2:  Udalit ochered iz massiv');
  Writeln ('3:  Prosmotr massiv');
  Writeln ('4:  Poisk ocheredi v massiv');
  Writeln ('5:  Sohranit massiv');
  Writeln ('6:  Zagruzit massiv');
  Writeln ('0:  Exit');
  Writeln ('===========================================');
  Write('Vibor : ');
  Readln (key);
 case key of
      1: AddMasQ(mass , x);
      3: ScanMasQ(mass , x);
    end;
  until key=0;
END.

Последний раз редактировалось diliana; 11.11.2009 в 22:00.
diliana вне форума Ответить с цитированием
Старый 11.11.2009, 13:23   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
diliana
Я бы делал так:
1. Хранил в некой переменной индекс последнего элемента, массива, всмысле последнего не пустого.

2. при добавлении ты создаешь через new очередь, и адрес на нее (имеется ввиду на ее голову) пишешь в массив[его последний элемент] предварительно увеличив его последний элемент на единицу и проверив не вылезает ли он за пределы.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 11.11.2009, 14:00   #3
diliana
Форумчанин
 
Аватар для diliana
 
Регистрация: 24.05.2009
Сообщений: 119
По умолчанию

Stilet

А вы можете это показать, теоритически я это представляю, но как практически реализовать ???
diliana вне форума Ответить с цитированием
Старый 11.11.2009, 14:40   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Да запросто:
Код:
program Project1;

 Type
  PTP=^tp;
  tp=record
    i:integer;
    next:PTP;
  end;

 var a:array[1..10] of PTP;
// Это индекс последнего элемента
  lastA,e:integer;
  item:PTP;

// Процедура добавляющая в хвост массива новый элемент и устанавливающая на него хвост
 Function AddA:PTP;
 begin
  lastA:=lastA+1;
  new(a[lasta]);
  AddA:=a[lasta];
 end;

begin
 lastA:=0;
 item:=AddA; item^.i:=10;
 item:=AddA; item^.i:=20;
 item:=AddA; item^.i:=30;

 for e:=1 to 10 do begin
  if a[e]<>nil then begin
   write(a[e]^.i:10);
  end;
 end;

 readln;

  { TODO -oUser -cConsole Main : Insert code here }
end.
Так ясно? Или обширнее коментарии прописать?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 11.11.2009, 15:10   #5
diliana
Форумчанин
 
Аватар для diliana
 
Регистрация: 24.05.2009
Сообщений: 119
По умолчанию

Код:
lastA:=0; // Это индекс последнего элемента  
item:=AddA; // присвоено значение выполнения функции
item^.i:=10; //<----это что такое ???
item:=AddA; 
item^.i:=20;
item:=AddA; 
item^.i:=30;
извините, но честно говоря мне не очень ясно...

Последний раз редактировалось diliana; 11.11.2009 в 21:59.
diliana вне форума Ответить с цитированием
Старый 11.11.2009, 23:52   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

diliana, ну, я полностью согласен с мнением Виталия... единственное, что он не реализовал то, что сам и предложил - проверку того, что мы не достигли границы массива:
Код:
 Function AddA:PTP;
 begin
  if lastA = МаксимальныйРазмерМассива then 
      Выдаём_ошибку_в_массиве_больше_нет_места_для очередей
  else begin
    lastA:=lastA+1;
    ....
  end;
и я не могу понять, что вызывает у Вас затруднение.
Смотрите. создаём массив указателей. массив задаём СТАТИЧЕСКИЙ. размер - произвольно, заведомо большой, желательно больше, чем всего может быть очередей. Ну, например, как у Вас: N = 100
Дальше. Вводим переменную, которая показывает, какой последний элемент в массиве занят. Так сказать, указатель "хвоста" массива... в примере Виталия:
lastA:=0; // Это индекс последнего элемента
дальше. когда надо создать очередь, то мы увеличиваем индекс и указатель на созданную очередь записываем по этому индексу. никакие HeadQ нам не нужны, так как I-й элемент массива - это как раз указатель на первый (головной элемент) I-й очереди...

Возникает одна проблемка с удалением очереди из массива... НУ, скажем, хотим удалить очередь с индексом K
ну, сначала, разумеется удаляем элементы очереди (причём в цикле начиная от последних), но потом надо очистить MASS[K] (или A[K] - в примере Виталия). Но тут можно "в лоб" - просто все элементы массива, начиная с K+1 и до lastA переписать на место предыдущего:
MASS[K] := MASS[K+1]
MASS[K+1] := MASS[K+2]
и т.д.
а потом уменьшаем lastA на единицу....

подумайте немножко... нарисуйте на бумажке..
поверьте, ничего в этом сложного нет!

p.s. Если всё равно непонятно - тогда я могу набросать примерчик... но уж извините, только завтра днём...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 12.11.2009, 09:21   #7
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
он не реализовал то, что сам и предложил - проверку того, что мы не достигли границы массива:
Я решил чт нет смысла в этом раз массив образмерен четко.
Просто отсекать те элементы которые NIL и не париться...

Впрочем:
Код:
 for e:=1 to lastA do begin
   write(a[e]^.i:10);
 end;
Цитата:
но честно говоря мне не очень ясно...
item:=AddA; - Создает новый элемент, помещает его в конец массива, и возвращает на него ссылку
item^.i:=10; Во вновь созданный элемент помещаем некие данные (это пример не более)
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 12.11.2009, 11:29   #8
diliana
Форумчанин
 
Аватар для diliana
 
Регистрация: 24.05.2009
Сообщений: 119
По умолчанию

Вот написала так, но при выполнениии вылетает...
Где я ошибаюсь ?

Код:
{Функция, добавляющая в хвост массива новый элемент и
устанавливающая на него хвост}
Function Add_Mass_Last (var mass: TMassQu; LastA:integer): pQueue;
const
  N = 100;
begin
  if lastA = N then WriteLn ('Massiv zapolnen')// если больше_нет_места_для очередей
  else
   begin // иначе выделяем память для новой очереди
    lastA:=lastA+1;
    new(mass[LastA]);// выделить память для новой очереди
    Add_Mass_Last := mass [LastA]; // возвращаем результат функции
  end;
end;


Procedure AddMasQ(var mass: TMassQu; var x: integer);

var
  i, j, x_que, x_elem, k : integer;
  LastA : integer; {перем-я, кот. показывает,
                  какой последн.элем-т в массиве занят}
  temp, HeadT, LastT: pQueue;

begin
  {вводим число элементов (очередей)  массива }
  write ('Vvesti chislo elementov massiva : ');
  readln (x_que);
  LastA:=0; // Это индекс посл-го элем-та массива
  temp := Add_Mass_Last (mass, LastA);
  k:=0;
  FOR i := 1 To x_que Do
       begin
       HeadT := nil; LastT := nil;{создаем пустую очередь}
       Inc (k);// считаем очереди
       writeln(' * New ochered # : ', k);
       write(' * Vvesti chislo elementov ocheredi: ');
       readln(x_elem);
       FOR j := 1 to x_elem do
        begin
         write('    element # ', j);
         AddQ(HeadT, LastT);{заполняем очередь элементами}
        end;
        write( mass[i]^.data);
  writeln;
  end;
end;
diliana вне форума Ответить с цитированием
Старый 12.11.2009, 12:21   #9
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
но при выполнениии вылетает...
В таких случаях пошагам по программе проходятся - поверь мне это лучший способ.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 12.11.2009, 12:59   #10
diliana
Форумчанин
 
Аватар для diliana
 
Регистрация: 24.05.2009
Сообщений: 119
По умолчанию

Stilet

А почему вы не говорите, правильно или нет, сделан код процедуры
добавления очереди в этот массив???
diliana вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Перепись значений в массив указателей. Джед Общие вопросы C/C++ 9 28.05.2009 18:12
Массив. Паскаль Fintos Помощь студентам 1 24.04.2009 04:37
массив указателей на методы класса? cout Общие вопросы C/C++ 2 08.05.2008 09:43
Массив указателей на структуры SNAKE89 Общие вопросы C/C++ 4 27.12.2007 10:14