Страница 1 из 2
динамические структуры в паскале
Добавлено: 29 апр 2007, 11:36
Alex_Burn
Здравствуйте, уважаемые участники форума!
Не могли бы вы помочь мне отыскать ошибку в рассуждениях?
Вот какое у меня задание:
Разработать программу, которая удаляет из списка все элементы, меньше заданного пользователем значения k. Список строится путем ввода с клавиатуры значений элементов. Количество элементов заранее не известно, но отлично от нуля. Процедуры и функции для работы со списком (такие как формирование списка, поиск элемента по ключу, удаление элемента списка, просмотр списка и т.п.) оформить в виде модуля.
Вот какой модуль я пытался составить:
Код: Выделить всё
unit list;
interface
uses crt;
const n=10;
type ukaz=^k;
k=record
inf:integer;
next:ukaz;
end;
var nlst,klst,pc,p,px:ukaz;
c:array[1..n] of integer;
i,key:integer;
flag:boolean;
procedure fill(var nlst:ukaz);
procedure survey(nlst:ukaz);
procedure search(var key:integer; nlst,p:ukaz; flag:boolean);
procedure delete(var key:integer; nlst:ukaz);
implementation
procedure fill(var nlst:ukaz);
begin
for i:=1 to n do
begin
new(p);
p^.inf:=c[i];
p^.next:=nlst;
nlst:=p;
end;
end;
procedure survey(nlst:ukaz);
begin
write('Содержание списка: ');
p:=nlst;
if nlst<>nil then
repeat
write(p^.inf,' ');
p:=p^.next;
until p=nil;
end;
procedure search(var key:integer; nlst,p:ukaz; flag:boolean);
begin
p:=nlst;
flag:=false;
while (p<>px) and (not flag) do
begin
if p^.inf<key
then flag:=not flag
else
begin
px:=p;
p:=p^.next;
end;
end;
end;
procedure delete(var key:integer; nlst:ukaz);
var p,px:ukaz;
begin
search(key,nlst,p,flag);
px^.next:=p^.next;
dispose(p);
p:=nil;
end;
end.
Но программа, использующая этот модуль не работает. Помогите пожалуйста разобраться, почему.
Заранее благодарен!
Re: динамические структуры в паскале
Добавлено: 29 апр 2007, 14:25
Duncon
Ошибка тут(дальше не смотрел)
Ты объявляешь некую переменную ukaz ссылкой на запись и внутри нее переменная next которая будет ссылкой на саму себя, ппс даже объяснить нормально не могу такой бред...
Код: Выделить всё
type ukaz=^k;
k=record
inf:integer;
next:ukaz;
end;
Писать нужно примерно так
Код: Выделить всё
type
k = record
inf: integer;
next: string; //(ну или чем у тебя является по задумке данная переменная)
end;
ukaz=^k;
Re: динамические структуры в паскале
Добавлено: 29 апр 2007, 23:43
Naeel Maqsudov
Duncon, синтаксических ошибок тут нет.
Разьве что в третьей строке снизу буковка "х" попала.... Наверное случайно.
А "такой бред" - это специальное исколючение языка Паскаль для работы со списками. Оно заключается в том, что без слова forward разрешается объявлять взаиморекурсивные типы данных.
Re: динамические структуры в паскале
Добавлено: 29 апр 2007, 23:54
Naeel Maqsudov
Alex_Burn, к сожалению нет много времени разбираться, но могу сказать следующее.
1) процедура fill - не является решением поставленной задачи, так как количество элементов задано констанотой, а к тому же процедура создает список из массива, а не вводом с клавиатуры.
2) процедура survey нормально выводит список
3) процедура delete использует глобальные переменные p и flag - этого не следует делать. Вообще в delete что-то несуразное написано.
4) не понял с первого взгляда, что делает параметр flag в процедуре search
Код основной программы тоже в студию!
Вцелом (как бывший преподаватель ИТ в ВУЗе) могу сказать, что это работа на "незачет".
Re: динамические структуры в паскале
Добавлено: 01 май 2007, 11:02
Alex_Burn
Ещё раз здравствуйте, уважаемые участники форума.
Прошу прощения, что не принимал участия в дискуссии вчера и позавчера (не было доступа к интернету).
Что касается модуля, то я, в принципе, не понял тему (в смысле про динамические структуры). Поэтому и написал полный бред. Да и менял я код уже 10 раз (возможно с каждым разом получалось все бредовее).
Что касается главной программы, то что-то в этом духе:
Код: Выделить всё
program lst;
uses crt, list;
begin
clrscr;
writeln('введите числа для занесния в список(10 чисел)');
for i:=1 to n do read(c[i]);
fill(nlst);
survey(nlst);
writeln('введите число (все числа меньше введенного будут удалены из списка)');
readln(key);
writeln;
delete(key,nlst);
survey(nlst);
readkey;
end.
Не мог бы кто-нибудь из вас подсказать мне как правильно все это сделать, а то сам никак не разберусь.
Заранее благодарен.
Re: динамические структуры в паскале
Добавлено: 02 май 2007, 14:58
Alex_Burn
не могли бы вы поделиться своими мыслями по поводу задачи, которую я выложил в начале темы? как ее лучше реализовать? выручайе...

Re: динамические структуры в паскале
Добавлено: 03 май 2007, 03:12
Игорь Акопян
Alex_Burn,
процедуру Fill переделать - убрать цикл for, спросить количество и заполнять в цикле while
Да и вообще надо переделать алгоритм, чтобы было понятнее:
1) Функция Search по идее должна искать в списке элемент равный ключу, принимает 2 параметра - ключ и указатель на начало, возвращает указатель на найденный элемент. Но для решения задачи она не нужна, ибо надо делать полный перебор элментов списка в цикле
2) Процедура Delete должна удалять элемент из списка, переданный в качестве параметра.
3) В теле программы в цикле while бежим по всем элементам, и если значение меньше заданного вызываем Delete на текущий элемент
Полагаю что остальные процедуры должны быть как заготовка на случай изменения условия задачи
Re: динамические структуры в паскале
Добавлено: 07 май 2007, 03:21
Naeel Maqsudov
Код: Выделить всё
program lst;
uses crt, list;
var
nlst:ukaz;
key:integer;
begin
clrscr;
if fill(nlst)>0 then begin
survey(nlst);
writeln('введите число (все числа меньше введенного будут удалены из списка)');
repeat until getnumber(key)=gnOk;
search_n_del(key,nlst);
survey(nlst);
end
else writeln('Был введен пустой список');
readkey;
end.
==========================================================
unit list;
interface
uses
crt;
const
n=10;
type
ukaz=^k;
k=record
inf:integer;
next:ukaz;
end;
getnumberstatus = (gnOk,gnStop,gnErr);
function getnumber(var X:integer):getnumberstatus;
function fill(var nlst:ukaz):integer;
procedure add(val:integer; var nlst:ukaz);
procedure survey(nlst:ukaz);
procedure search_n_del(key:integer; var nlst:ukaz);
procedure deletefirst(var nlst:ukaz);
procedure deletenext(pred:ukaz);
implementation
function getnumber(var X:integer):getnumberstatus;
var
s:string; code:integer;
begin
readln(s);
if s='' then getnumber:=gnStop else begin
val(s,X,code);
if code=0 then getnumber:=gnOk else getnumber:=gnErr;
end
end;
function fill(var nlst:ukaz):integer;
var
i,r:integer;
p:ukaz;
begin
r:=0;
nlst:=nil;
writeln('Введите числа, для завершения ввода нажмите Enter');
repeat
case getnumber(i) of
gnOk: begin
add(i, nlst);
inc(r);
end;
gnErr: writeln('Ошибка! Неверное число');
gnStop: break;
end;
until false;
fill:=r;
end;
procedure add(val:integer; var nlst:ukaz);
var
p:ukaz;
begin
new(p);
p^.inf:=val;
p^.next:=nlst;
nlst:=p;
end;
procedure survey(nlst:ukaz);
var
r:integer;
begin
r:=0;
write('Содержание списка: ');
while nlst<>nil do begin
write(nlst^.inf);
if nlst^.next<>nil then write(', ') else writeln('.');
nlst:=nlst^.next;
inc(r);
end;
writeln('Всего ',r,' элементов');
end;
procedure search_n_del(key:integer; var nlst:ukaz);
var
p:ukaz;
begin
p:=nlst;
while (p<>nil) and (p^.next<>nil) do begin
if p^.next^.inf < key then deletenext(p) else p:=p^.next;
end;
if (nlst<>nil) and (nlst^.inf<key) then deletefirst(nlst);
end;
procedure deletenext(pred:ukaz);
var
p:ukaz;
begin
if (pred<>nil) and (pred^.next<>nil) then begin
p:=pred^.next;
pred^.next:=p^.next;
dispose(p);
end;
end;
procedure deletefirst(var nlst:ukaz);
var
p:ukaz;
begin
if nlst<>nil then begin
p:=nlst;
nlst:=nlst^.next;
dispose(p);
end;
end;
end.
Re: динамические структуры в паскале
Добавлено: 07 май 2007, 03:31
Naeel Maqsudov
функция getnumber вводит число с клавиатуры. Обеспечивает проверку ошибок и позволяет распознать пустой ввод (используется как сигнал конца списка).
функция fill заполняет список с клавиатуры. Пользуется процедурой add для добавоения элемента в начало списка. Результат функции - это сколько элементов было введено. В основной программе проверяется, но можно и не проверять, так как программа и с пустыми списками работает корректно.
процедура survey - то же что раньше, но теперь перечисляет все элементы через запятую, и сообщает длину списка (А чего по списку лазить задаром!

)
search_n_del - решает поставленную задачу. Сначала просматривает все со второго элемента, а в заключение проверяет, не надо ли удалить первый. Так чделано потому, что в односвязном списке нельзя удалить элемент, заданный указателем. Можно удалить только следующий, от заданного указателем.
(т.е. конечно же элемент заданный указателем удалить можно, но в предыдущем надо подправить next, а искать его надо полным перебором от начала. Так что более эффективный алгоритм - это начать провыерять со второго, а потом проверить первый.
Re: динамические структуры в паскале
Добавлено: 07 май 2007, 03:38
Naeel Maqsudov
Alex_Burn писал(а):не могли бы вы поделиться своими мыслями по поводу задачи, которую я выложил в начале темы? как ее лучше реализовать? выручайе...
Готово.
2 All
Все посторонние рассуждения я перенес
в другую тему