Удалить из списка все элементы, входящие в него в точности 2 раза - Free Pascal
Формулировка задачи:
Дан список из n целых чисел a1,a2,..,an. Удалить из списка все элементы, входящие в него в точности 2 раза.
Программа работает, но иногда выдает такую ошибку.
Как исправить?
program L02; uses crt; type PList = ^TList; TList = record a: integer; pred, next: PList; end; var head: PList; n: integer; {Формирование списка} procedure FormList(var head: PList; n: byte); var p, q: PList; i: byte; begin{FormList} randomize; new(head); {Сторож - головной элемент} head^.next := nil; head^.pred := nil; p := head; for I := 1 to n do begin new(q); q^.a := random(10); q^.pred := p; q^.next := nil; p^.next := q; p := q; end; end;{FormList} {Вывод списка на экран} procedure PrintList(head: PList); var p: PList; begin{PrintList} p := head^.next; while p <> nil do begin write(p^.a:6); p := p^.next; end; writeln; end;{PrintList} procedure Delete(head: PList); var p, q, q2: PList; c: integer; begin{Delete} p := head^.next; while p <> nil do begin c := 0; // q:=p^.next; q := head^.next; // начинаем всегда с самого начала списка, а не со следующего за P элемента while q <> nil do begin if p^.a = q^.a then begin if p <> q then q2 := q; // тот элемент, куда указывает p, запоминать не надо, мы и так знаем про него c := c + 1; end; q := q^.next; end; if c = 2 then // Если их ровно 2, то первый - это тот, куда указывает p, а второй - q2 begin q := p; // удаляем первый q^.pred^.next := q^.next; q^.next^.pred := q^.pred; p := p^.next; dispose(q); q := q2; // и второй, с учетом, что он может оказаться прямо за первым q^.pred^.next := q^.next; q^.next^.pred := q^.pred; if(q = p) then p := p^.next; // тогда продвигаемся дальше dispose(q); printlist(head); end else p := p^.next; end; end;{Delete} begin ClrScr; writeln('-----------------------------------------------------------'); writeln('Программа генерирует случайными значениями линейный список,'); writeln(' затем удаляет из него элементы,которые встречаются '); writeln('2 раза '); writeln('-----------------------------------------------------------'); writeln('Введите количество элементов списка'); readln(n); FormList(head, n); writeln('Исходный список:'); PrintList(head); Delete(head); writeln('Список после удаления элементов,встречающихся 2 раза:'); PrintList(head); end.
Решение задачи: «Удалить из списка все элементы, входящие в него в точности 2 раза»
textual
Листинг программы
if c = 2 then // Если их ровно 2, то первый - это тот, куда указывает p, а второй - q2 begin q := p; // удаляем первый if (q^.pred <> nil) then q^.pred^.next := q^.next; if (q^.next <> nil) then q^.next^.pred := q^.pred; p := p^.next; dispose(q); q := q2; // и второй, с учетом, что он может оказаться прямо за первым if (q^.pred <> nil) then q^.pred^.next := q^.next; if (q^.next <> nil) then q^.next^.pred := q^.pred; if(q = p) then p := p^.next; // тогда продвигаемся дальше dispose(q); printlist(head); end
Объяснение кода листинга программы
В данном коде на языке Free Pascal реализован алгоритм удаления из списка всех элементов, входящих в него в точности 2 раза.
- Проверка условия: Если c = 2, то есть если элемент встречается ровно дважды, то мы переходим к следующему шагу.
- Удаление первого: Мы сохраняем указатель на первый элемент списка, затем удаляем его. Если перед первым элементом есть другие элементы, то мы обновляем ссылку на следующий элемент перед первым. Если после первого элемента есть другие элементы, то мы обновляем ссылку на предыдущий элемент после первого. Затем мы переходим к следующему элементу списка.
- Удаление второго: Мы сохраняем указатель на второй элемент списка, затем удаляем его. Если перед вторым элементом есть другие элементы, то мы обновляем ссылку на следующий элемент перед вторым. Если после второго элемента есть другие элементы, то мы обновляем ссылку на предыдущий элемент после второго. Затем мы переходим к следующему элементу списка.
- Проверка условия: Если второй и первый элементы списка совпадают, то мы переходим к следующему шагу.
- Продвижение по списку: Мы обновляем указатель на голову списка, чтобы перейти к следующему элементу.
- Печать списка: Мы печатаем список. В итоге, после выполнения данного кода, в списке останутся только те элементы, которые встретились в списке не более одного раза.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д