Помощь - Поиск - Пользователи - Календарь
Полная версия: ОДнонаправленные линейные списки
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Тёмный Эльф
Текст программы приведен ниже. Не могу понять, в чем моя ошибка. Вроде бы первая процедура составляет список1 из первого файла, вторая процедура составляет список2 из второго файла, третья процедура собственно проверяет есть ли в списке 1 слова из списка 2 и если есть, удаляет их. А четвёртая процедура выводит изменённый список 1 в выходной файл.
Если кто заметил ошибку, подскажите пожалуйста где она, может я не правильно передаю параметры при заходе в третью процедуру?


Type
next=^elem;
Elem=RECORD
     EL:string;
     Sled:next;
     END;
VAR
head,head2:next;

Procedure p1(var p:next);
var
m:next;
F1:text;
BEGIN
  Assign(f1,'dan.inp');
  Reset(f1);
  Assign(output,'res.out');
  Rewrite(output);
 New(m);
 New(m^.sled);
 p:=m;
 Readln(f1, m^.el);
 m^.sled:=nil;
 while not EOF(f1) do
 begin
 New(m^.sled);
 m:=m^.sled;
 Readln(f1, m^.el);
 m^.sled:=nil;
 End;
 Close(f1);
end;

Procedure p2(var p:next);
var
m:next;
F1:text;
BEGIN
  Assign(f1,'dan1.inp');
  Reset(f1);
 New(m);
 New(m^.sled);
 p:=m;
 Readln(f1, m^.el);
 m^.sled:=nil;
 while not EOF(f1) do
 begin
 New(m^.sled);
 m:=m^.sled;
 Readln(f1, m^.el);
 m^.sled:=nil;
 End;
 Close(f1);
end;

procedure p3(var uk,d2:next);
var pp,df,q:next;
Begin
pp:=uk;
 While pp^.sled<>NIL  do
   BEGIN
   df:=d2;
 While df^.sled<>NIL do
    Begin
     If pp=df then
       Begin
       q:=pp^.sled^.sled;
       Dispose(pp^.sled);
       pp^.sled:=q;
       end;
df:=df^.sled;
end;
pp:=pp^.sled;
end;
END;

procedure p4(var dr:next);
var dt:next;
Begin
writeln('=======REZULTAT=======');
dt:=dr;
 While dt<>NIL do
 Begin
 Writeln(dt^.el);
 dt:=dt^.sled;
 End;
 close(output);
end;

BEGIN
p1(head);
p2(head2);  
p3(head,head2);			
p4(head); 
END.

volvo
Сразу вопрос на засыпку: в чем, собственно, разница между P1 и P2? Только в имени файла? Тогда передавай его, как параметр, и убирай одну процедуру - ибо в трех процедурах ошибиться сложнее, чем в четырех...
Тёмный Эльф
Да, я так для начала и сделал. Но если честно мороки больше вышло, я так решил сделать. По сути, с p1 получаю первый список, с p2 получаю второй список и потом спокойно сравниваю их. Вот, может, я делаю ошибку при передаче параматров в процедуру p3? Я для пробы в первый файл ввел цифры(каждая на отдельной строчке) 12345678, во второй файл я записал 135, то есть в результате в выходном файле должны остаться цифры 24678. Но

If pp=df then...
вообще получается, что это условие ни разу не исполняется, как будто то бы второй список пуст (хотя я его заполнял). (!) Не понимаю!
volvo
If pp=df then... 
Вот кстати об этом условии я и хотел с тобой поговорить... Что оно должно означать? Равенство указателей (согласно синтаксису Паскаля)? Так ведь дело в том, что ДАЖЕ указатели на один и тот же участок памяти могут не быть одинаковыми, тем более не будут одинаковы указатели на разные участки памяти...

Тебе бы делать
If pp^.EL = df^.EL Then ...
(ну, или pp^.sled^.EL = ...)
Тёмный Эльф
А ведь и правда! Здесь я сглупил!
Теперь в выходном файле 134578. Значит, можно сделать вывод, что моя очередная ошибка вот в
этих операторах:
 
       q:=pp^.sled^.sled;
       Dispose(pp^.sled);
       pp^.sled:=q;
   


(!)
volvo
yes2.gif
Во-первых, ты не идешь до конца списка, а зачем-то оставляешь один элемент, поэтому одно слово из второго списка ты в первом не найдешь однозначно... Ну, и с самим удалением проблема...

Вот так будет лучше:
procedure p3(var uk,d2:next);
var pp,df,q:next;
Begin

  pp:=uk;
  While pp<>NIL  do BEGIN
    df:=d2;
    While df<>NIL do Begin

      if pp^.el = df^.el then begin

        q:=pp^.sled;
        pp^.el := q^.el;
        pp^.sled := q^.sled;
        Dispose(q);

      end;
      df:=df^.sled;

    end;
    pp:=pp^.sled;
  end;

END;
Тёмный Эльф
Цитата
ты не идешь до конца списка

Точняк! Впредь буду более внимателен. Спасибо за подсказку, нашли целых три ошибки! wacko.gif smile.gif
Тёмный Эльф
А кстати, программа почему-то не хочет удалять последний элемент. Компилятор выдает ошибку 204 !
volvo
"Последний элемент" - это тот, PP, для которого PP^.sled = nil? Так правильно, что ошибка:

        q:=pp^.sled; { q = nil }
        pp^.el := q^.el; { Здесь вообще что-то невообразимое - pp^.el := nil^.el ??? }
        pp^.sled := q^.sled; { переход по нулевому указателю ... }
        Dispose(q); { Вызов Dispose(nil) ... }

Любой из этих операторов по отдельности завершит программу аварийно, а уж все вместе... wacko.gif

Добавляй условие - все это надо делать ТОЛЬКО если q <> nil ... Вот уже четвертая ошибка smile.gif
Тёмный Эльф
Цитата
Добавляй условие - все это надо делать ТОЛЬКО если q <> nil


Не знаю..не идет.. Может пустить счетчик? И потом отдельно удалять последний элемент если счетчик дошел до последней строки файла 1?
volvo
Так тоже не идет?
procedure p3(var uk,d2:next);
var pp,df,q:next;
Begin

  pp:=uk;
  While pp<>NIL  do BEGIN
    df:=d2;
    While df<>NIL do Begin

      if pp^.el = df^.el then begin

        q:=pp^.sled;
        if q <> nil then begin
          pp^.el := q^.el;
          pp^.sled := q^.sled;
          Dispose(q);
        end
        else begin
          pp := uk;
          while pp^.sled^.sled <> nil do pp := pp^.sled;
          dispose(pp^.sled);
          pp^.sled := nil;
        end

      end;
      df:=df^.sled;

    end;
    pp:=pp^.sled;
  end;

END;

Тёмный Эльф

Цитата
dispose(pp^.sled);
nea.gif

Ну да. Он все-равно в этом месте выдает ошибку. Не хочет никак последний элемент удалять!
volvo
"Не верю !!!" (С) ...

Только что прогнал программу у себя - все работает... Проверяй, что еще изменял...
Тёмный Эльф
Ну я бы не стал врать! На самом деле не шло! Я вот так сделал:

 
procedure p3(var uk,d2:next);
label g;
var pp,df,q:next;
Begin
pp:=uk;
 While pp<>NIL do Begin
 df:=d2;
  While df<>NIL do Begin

  if pp^.el=df^.el then begin

 g:     If q=nil then BEGIN  
	       pp:=uk;
	       q:=uk;
	       While pp^.sled<>NIL DO
		 Begin
		   q:=pp;
		   pp:=pp^.sled;
		 END;
		 DISPOSE(pp);
		 q^.sled:=NIL;
		 END else

		 BEGIN

		 q:=pp^.sled; if q=nil then goto g;
		 pp^.el:=q^.el;
		 pp^.sled:=q^.sled;
		 Dispose(q);
		 END;

    END;

      df:=df^.sled;
      end;
      pp:=pp^.sled;
     end;

  END;


Теперь работает. Уфф..
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.