![]() |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
![]() ![]() |
![]() |
LivingShadow |
![]()
Сообщение
#1
|
Группа: Пользователи Сообщений: 2 Пол: Мужской Репутация: ![]() ![]() ![]() |
Здравствуйте, уважаемые форумчане. Есть такое задание:
Удалить из списка один элемент после первого элемента с нулевым значением, если его значение отлично от него. Написал я для этого дела такую процедуру:
procedure DelX(var start:link);
var p,pr:link;
k:integer;
begin
Writeln('Удаление из списка первого элемента после нуля (если это не ноль)');
k:=0;
p:=start;
while (k=0) AND (p<>nil) do
begin
if (p^.inf=0) then
begin
p:=p^.next;
if (p^.inf=0) then k:=1
else
begin
pr^.next:=p^.next;
dispose(p);
p:=pr^.next;
k:=1;
end;
end
else begin pr:=p; p:=p^.next; end;
end;
if k=0 then writeln('Ни одного нуля не найдено.');
Write('Нажмите любую клавишу');
readln;
end;
Но она очевидно неправильная. Во-первых, когда после нуля идет число, то она удаляет не только это число, но и сам нуль. Когда два нуля подряд - все нормально. Во-вторых программа вылетает, когда список начинается с нуля. Буду очень благодарен, если сможете указать на мои ошибки. |
volvo |
![]()
Сообщение
#2
|
Гость ![]() |
Ну, вылетает тебя процедура по самой распространенной причине: невнимательность. Вот тут:
Цитата pr^.next:=p^.next;
А вообще - несколько сумбурно ты решаешь задачу. Я бы делал так: // Во-первых, напрасно ты передаешь start как Var-параметр.
// Первый элемент списка не будет удален никогда. Он либо не 0 и его пропустишь,
// либо он 0, и тогда в лучшем случае удалится следующий за ним...
procedure DelX(start: link);
var
p, pr: link;
begin
// Начали:
p := start;
repeat
// для начала - пропускаем все ненулевые элементы, при этом
// следя за концом списка, чтоб без неожиданностей...
while (p <> nil) and (p^.inf <> 0) do p := p^.next;
// когда мы тут - это значит либо нашли 0, либо дошли до конца списка
// если дошли до конца - то p = nil, и внутрь If мы просто не попадаем...
if p <> nil then
begin
// ага, мы тут, значит, p указывает на элемент равный 0...
// запомним его (вдруг следующий будем удалять) и переходим к следующему...
pr := p;
p := p^.next;
// Не вылезли из списка? Не нулевой элемент? Удаляем и правим указатель от предыдущего...
// после удаления выходим из процедуры !!!
if (p <> nil) and (p^.inf <> 0) then
begin
pr^.next := p^.next;
dispose(p); exit;
end;
end;
// не вышли из процедуры? Одно из двух. Либо конец списка, либо несколько нулей подряд
// в случае конца списка p = nil, и цикл repeat заканчивается, иначе - продолжаем поиск...
until p = nil;
end;
Что непонятно - задавай вопросы. Упустишь - потом будешь плавать в динамических структурах... ![]() |
LivingShadow |
![]()
Сообщение
#3
|
Группа: Пользователи Сообщений: 2 Пол: Мужской Репутация: ![]() ![]() ![]() |
Ох, спасибо огромное. Насчет плавать - это вы абсолютно в точку, упустил эту тему почти полностью (раньше знал, думал что и сейчас без проблем вспомню), в итоге пришлось рассматривать её полностью на чужих примерах, которые сами по себе были далеко от оптимальных =) Так что вот сейчас ещё параллельно делаю задания по двусвязным спискам и деревьям - получается все также криво (а сдавать-то уже сегодня надо)
Конкретно по этому вопросов нет, комментарии весьма подробны, ошибки свои осознал, ещё раз спасибо! |
![]() ![]() |
![]() |
Текстовая версия | 28.07.2025 3:22 |