Удалить из списка все элементы, входящие в него в точности 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 раза.

  1. Проверка условия: Если c = 2, то есть если элемент встречается ровно дважды, то мы переходим к следующему шагу.
  2. Удаление первого: Мы сохраняем указатель на первый элемент списка, затем удаляем его. Если перед первым элементом есть другие элементы, то мы обновляем ссылку на следующий элемент перед первым. Если после первого элемента есть другие элементы, то мы обновляем ссылку на предыдущий элемент после первого. Затем мы переходим к следующему элементу списка.
  3. Удаление второго: Мы сохраняем указатель на второй элемент списка, затем удаляем его. Если перед вторым элементом есть другие элементы, то мы обновляем ссылку на следующий элемент перед вторым. Если после второго элемента есть другие элементы, то мы обновляем ссылку на предыдущий элемент после второго. Затем мы переходим к следующему элементу списка.
  4. Проверка условия: Если второй и первый элементы списка совпадают, то мы переходим к следующему шагу.
  5. Продвижение по списку: Мы обновляем указатель на голову списка, чтобы перейти к следующему элементу.
  6. Печать списка: Мы печатаем список. В итоге, после выполнения данного кода, в списке останутся только те элементы, которые встретились в списке не более одного раза.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 3.714 из 5
Похожие ответы