Помощь - Поиск - Пользователи - Календарь
Полная версия: Сложение элементов 2 списков
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Tribunal
мне нужно произвести сложение
2 списков поэлементно...

вот то,что я делаю,но при выполнении собственно сложения выдается ошибка

read(n);
randomize;

new(first);{создание первого списка}
first^.next:=nil;
first^.inf:=random(10)-1;
for i:=1 to n-1 do
begin
new(p1);
p1^.inf:=random(10)-1;
p1^.next:=nil;
p1^.next:=first;
first:=p1;
end;
t:=p1;
while t<>nil do
begin
writeln(t^.inf);
t:=t^.next;
end;

new(first);{создание второго списка}
first^.next:=nil;
first^.inf:=random(10)-1;
for i:=1 to n-1 do
begin
new(p2);
p2^.inf:=random(10)-1;
p2^.next:=nil;
p2^.next:=first;
first:=p2;
end;
t:=p2;
while t<>nil do
begin
writeln(t^.inf);
t:=t^.next;
end;

new(first);{выполнение сложения}
first^.next:=nil;
first^.inf:=p1^.inf+p2^.inf;
p1:=p1^.next;
p2:=p2^.next;
while p1<>nil do
while p2<>nil do
begin
new(p3);
p3^.inf:=p1^.inf+p2^.inf;
p3^.next:=nil;
p3^.next:=first;
first:=p3;
p1:=p1^.next;
p2:=p2^.next;
end;

t:=p3;
while t<>nil do
begin
writeln(t^.inf);
t:=t^.next;
end;


помогите,пожалуйста,понять,в чем тут дело...
Tribunal
всё)эту глупую ошибку нашла...
а почему получается только один элемент в результирующем списке?
volvo
Ну, поскольку у тебя списки P1 и P2 одинаковой длины, то достаточно будет сделать так:

if (p1<>nil) and (p2<>nil) then begin

new(first); { выполнение сложения }
first^.next:=nil;
first^.inf := p1^.inf + p2^.inf; { Ошибка была тут: P3 еще не инициализирован... }
p1:=p1^.next; p2:=p2^.next;
while p1<>nil do begin { второе условие проверять необязательно }
new(p3);
p3^.inf:=p1^.inf+p2^.inf;
p3^.next:=nil;
p3^.next:=first;
first:=p3;
p1:=p1^.next; p2:=p2^.next;
end;

end;
Tribunal
а результирующий список выводится в обратном порядке))
этого можно избежать?или мне список инвертировать?)
volvo
Цитата(Tribunal @ 9.05.2006 12:07)
а результирующий список выводится в обратном порядке))

Точно так же, как и исходные blum.gif

Можно список инвертировать, можно просто по-другому его создавать, чтобы он сразу создавался в "прямом" порядке... Что выбираешь?
Tribunal
но факт в том,что они создаются в разных порядках...)
а в прямом порядке это как?
Tribunal
так получается,что в тот момент,когда мы обращаемся к спискам p1 и p2 их куазатели стоят в конце после вывода их на экран.так?
тогда поэтому и происходит так,что результат выводится в обратном порядке.
а как тогда обратиться к началу тех двух списков?

хотя нет.такого быть не может.тогда бы ссылки на следующий элемент не было(
volvo
Цитата(Tribunal @ 9.05.2006 12:22)
а в прямом порядке это как?

Вот так:
type
plist = ^list;
list = record
inf: integer;
next: plist;
end;

procedure create_list(var p: plist);
var
first, last, curr: plist;
i, X: integer;
begin
first := nil; last := nil;
for i := 1 to 5 do begin
write('item #', i:2, ' = '); readln(X);

new(curr);
curr^.inf := X;
curr^.next := nil;

if first = nil then first := curr
else last^.next := curr;

last := curr;
end;
p := first;
end;

var
p, p1: plist;

begin
create_list(p1);
p := p1; { <--- Это - чтобы не потерять начало списка, работаем через доп. переменную }
while p <> nil do begin
write(p^.inf:4);
p := p^.next;
end;
writeln;
end.


Посмотри, что делается в процедуре (и зачем добавлена не только переменная First, а еще и переменная Last), и добавляй элементы в список по этому принципу...
Tribunal
и всё же мне непонятно,почему последний список получается в обратном порядке...

и с переменной last разобраться не могу...
впрочем,я попыталась впихать эту процедуру себе в программу и всё равно ничего не получилось((

if (p1<>nil) and (p2<>nil) then
begin

first:=nil;
last:=nil;

while p1<>nil do
begin

new(t);
t^.inf:=p1^.inf+p2^.inf;
t^.next:=nil;
if first=nil
then first:=t
else last^.next:=t;
last:=t;

end;
p3:=first;
end;
volvo
Нет... Ты не должна ЭТО делать ТОЛЬКО в последнем списке... Первые 2 тоже должны быть так сформированы... Иначе ничего не получится...

И еще одно. Я привел тебе процедуру, а ты ее зачем-то "растворила" в основной программе. Смысл мне объясни... Ты что, думаешь, что 3 раза сделать Copy+Paste лучше, чем одну процедуру вызвать 3 раза? Отнюдь... Так зачем?
Tribunal
у меня вот есть такая процедура создания списка с добавлением элементов в конец списка:

new(first);
first^.next:=nil;
read(first^.inf);

for i:=1 to n do
begin
new(p);
read(p^.inf);
p^.next:=nil;
t:=first;
t^.next:=p;
t:=t^.next;
end;


только в ней что-то не так.только что?
Tribunal
кстати...
а покажите,пожалуйста,как инверитировать список)
volvo
var
p, p1: plist;
pt, prv, first, last: plist;

begin
create_list(p1); { Создаем список }

p := p1; { Печатаем "прямой" список }
while p <> nil do begin
write(p^.inf:4);
p := p^.next;
end;
writeln;

{ Инвертируем список }
first := p1;
if (first <> nil) and (first^.next <> nil) then begin

last := first;
while last^.next <> nil do last := last^.next;

pt := first; prv := nil;
first := last; last := pt;
while pt <> first do begin
p := pt^.next;
pt^.next := prv;
prv := pt;

pt := p;
end;
first^.next := prv
end;

p := first; { Печатаем инвертированный список }
while p <> nil do begin
write(p^.inf:4);
p := p^.next;
end;
writeln;
end.


Процедура create_list - та же самая, что и в моем предыдущем примере...
Tribunal
не могу понять многие моменты в инвертировании списка,
не получается прослеедить алгоритм...((
пожалуйста,если не трудно,не могли бы вы поподробнее объяснить?
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.