Помощь - Поиск - Пользователи - Календарь
Полная версия: Линейные Списки.
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
lopata
Только не позорьте. ;)
Вообще как бы программа преобразовывает строки в списки . То есть "Дом" становиться списком "Д" "О" "М".
Вот у меня функция для преобразования строки в список:

program CharList;
uses
crt;
type
NodePtr = ^Node;
Node = record
next: NodePtr;
ch: char;
end;
CharListPtr = NodePtr;

function CharListOf(s: string): CharListPtr;
var
List: CharListPtr;
prevNode, newNode: NodePtr;
i: integer;
begin
List := nil;
for i := 1 to length(s) do
begin
if (i = 1) then
begin
new(List);
List^.next := nil;
List^.ch := s[i];
prevNode := List;
end
else
begin
New(newNode);
newNode^.ch := s[i];
newNode^.next := nil;
prevNode^.next:= newNode;
prevNode := newNode;
end;
end;
prevNode := nil;
CharListOf := List;
end;

begin
charlistof('hello world!');
end.


Нужно написать функцию
FUNCTION CLConcat(cl1, cl2: CharListPtr): CharListPtr; (*returns concatenation of cl1 and cl2 by copying both lists*)

вот у меня получилось, но пока только для копирования одного списка:


FUNCTION CLConcat(cl1: CharListPtr): CharListPtr;
var cl3 ,PrevNode, NewNode, current:CharListPtr;
begin
New(cl3);
cl3^.ch := cl1^.ch;
cl3^.next := nil;
prevNode := cl3;
current := cl1;
while current <> nil do
begin
current := current^.next;
new(NewNode);
newNode^.ch := current^.ch;
prevNode^.next:= newNode;
prevNode := newNode;
end;
CLConcat := cl3;
end;



Подскажите что не правильно? не могу проверить правильно или нет, так как не понимаю как мне вызывать эту функцию.
Очень нуждаюсь в помощи.
volvo
Цитата
вот у меня получилось, но пока только для копирования одного списка:
А где у тебя в задании что-то сказано о копировании списков? У тебя стоит задача: есть 2 списка, и надо один приклеить к другому. Так? Это делается в три строки ровно:
function CLConcat(List1, List2: CharListPtr): CharListPtr;
begin
CLConcat := List1;
while List1^.next <> nil do List1 := List1^.next;
List1^.next := List2;
end;
Это НЕ сработает только в одном случае, если List1 будет пустым, это надо проверить отдельно, сделай это самостоятельно...
lopata
все. поняла. спасибо. можешь пожалуйста посмотреть процедуру:
PROCEDURE DisposeCharList(VAR cl: CharListPtr);
var
temp, current : NodePtr;
begin
current := cl;
while current <> nil do
begin
temp := current^.next;
dispose(current);
current := temp;
end;
end;

volvo
Ну, посмотрел... И что? Я бы сделал по-другому:
   current := cl;
while current <> nil do begin
temp := current; // запомнили
current := current^.next; // продвинулись дальше
dispose(temp); // удалили
end;
cl := current; // фактически: CL := nil
lopata
у меня возник вопрос : почему в самом начале функции ей присвается указатель?
volvo
Это не ей... Это результат, который она вернет. А вернуть она должна начало первого списка...
lopata
Блин.. А если я захочу скажем удалить из первого списка первый элемент?
получается что в склеином списке его тоже не будет...
volvo
Тогда тебе нужно именно копирование списка... Тем более, что
Цитата
Нужно написать функцию
FUNCTION CLConcat(cl1, cl2: CharListPtr): CharListPtr; (*returns concatenation of cl1 and cl2 by copying both lists*)
Вот так:
program CharList;

type
NodePtr = ^Node;
Node = record
next: NodePtr;
ch: char;
end;
CharListPtr = NodePtr;

procedure AppendToList(Ch: char; var First, Last: CharListPtr);
var p: CharListPtr;
begin
new(p);
p^.ch := ch; p^.next := nil;

if First = nil then First := p
else Last^.next := p;

Last := p;
end;

function CharListOf(s: string): CharListPtr;
var
Head, Tail: CharListPtr;
i: integer;
begin
Head := nil; Tail := nil;
for i := 1 to length(s) do
AppendToList(s[i], Head, Tail);
CharListOf := Head;
end;

function CopyList(L: CharListPtr): CharListPtr;
var Head, Tail: CharListPtr;
begin
Head := nil; Tail := nil;
while L <> nil do begin
AppendToList(L^.ch, Head, Tail); L := L^.next;
end;
CopyList := Head;
end;

function CLConcat(CL1, CL2: CharListPtr): CharListPtr;
var L: CharListPtr;
begin
L := CopyList(CL1);
CLConcat := L;
while L^.next <> nil do L := L^.next;
L^.next := CopyList(CL2);
end;

procedure PrintList(const L: CharListPtr);
begin
if L = nil then writeln
else begin
write(L^.ch:2); PrintList(L^.next);
end;
end;

var
L1, L2: CharListPtr;
LC: CharListPtr;
begin
L1 := CharListOf('hello ');
L2 := CharListOf('world!');

LC := CLConcat(L1, L2);
PrintList(LC);
end.
Попробуй разобраться, как это работает, и для чего введены доп. подпрограммы. Если что непонятно - спрашивай... Упустишь сейчас - потом будет труднее разобраться в работе с указателями...
lopata
У меня само задание это побороть ограниче типа стринг, переделывай его в списки, и использовать данные процедуры и функции :
FUNCTION NewCharList: CharListPtr; (*returns empty char list*)
PROCEDURE DisposeCharList(VAR cl: CharListPtr); (*disposes all nodes and sets cl to empty char list*)
FUNCTION CLLength(cl: CharListPtr): INTEGER; (*returns number of characters in cl*)
FUNCTION CLConcat(cl1, cl2: CharListPtr): CharListPtr; (*returns concatenation of cl1 and cl2 by copying both lists*)
FUNCTION CharListOf(s: STRING): CharListPtr;(*returns char list representation of STRING*)
FUNCTION StringOf(cl: CharListPtr): STRING; (*returns STRING representation of char list, may result in truncatation*)
Вот что сделала :
Program CharList;
Uses Wincrt;
TYPE
NodePtr = ^Node;
Node = RECORD
next: NodePtr;
ch: CHAR;
END; (*RECORD*)
CharListPtr = NodePtr;


FUNCTION CharListOf(s: STRING): CharListPtr;
var
List: CharListPtr;
prevNode, newNode: NodePtr;
i: integer;
begin
List := nil;
for i := 1 to length(s) do
begin
if (i = 1) then
begin
new(List);
List^.next := nil;
List^.ch := s[i];
prevNode := List;
end
else
begin
New(newNode);
newNode^.ch := s[i];
newNode^.next := nil;
prevNode^.next:= newNode;
prevNode := newNode;
end;
end;
prevNode := nil;
CharListOf := List;
end;

FUNCTION CLLength(cl: CharListPtr): INTEGER;
var current : NodePtr;
i : integer;
begin
i := 0;
current := cl;
while current <> nil do
begin
i := i + 1;
current := current^.next;
end;
CLLength := i;
end;
FUNCTION StringOf(cl: CharListPtr): STRING;
var current :NodePtr;
s : string;
begin
s := '';
current := cl;
while current <> nil do
begin
s := s + current^.ch;
current := current^.next;
end;
StringOf := s;
end;

PROCEDURE DisposeCharList(VAR cl: CharListPtr);
var
temp, current : NodePtr;
begin
current := cl;
while current <> nil do
begin
temp := current^.next;
dispose(current);
current := temp;
end;
end;

FUNCTION CLConcat(cl1, cl2: CharListPtr): CharListPtr;
begin
CLConcat := cl1;
while cl1^.next <> nil do cl1 := cl1^.next;
cl1^.next := cl2;
end;

begin

end.

volvo
Ты об этом говоришь ТЕПЕРЬ? Ну, извини, меня задания "по частям" не очень интересуют... Вернее, не интересуют вообще. Дальше - без меня...
lopata
Ну Извини. Меня интересовало как склеить списки.
lopata
Вот такая вот у меня получилась функция для склеивания списков..:

FUNCTION CLConcat(cl1, cl2: CharListPtr): CharListPtr;
var cl3 ,PrevNode, NewNode, current:CharListPtr;
begin
current := cl1;
prevNode := nil;

while current <> nil do
begin
new(NewNode);
newNode^ := current^;
newNode^.next := nil;
if (prevNode <> nil) then
begin
prevNode^.next:= newNode;
end
else
begin
cl3 := newNode;
end;
prevNode := newNode;
current := current^.next;
end;

current := cl2;
while current <> nil do
begin
new(NewNode);
newNode^ := current^;
newNode^.next := nil;
if (prevNode <> nil) then
begin
prevNode^.next:= newNode;
end
else
begin
cl3 := newNode;
end;
prevNode := newNode;
current := current^.next;
end;


lopata
yahoo!.gif ponyala i rayobralas' so spiskami) i teper' ochen' dovol'na soboj)
Lapp
Цитата(lopata @ 18.12.2009 11:03) *
yahoo!.gif ponyala i rayobralas' so spiskami) i teper' ochen' dovol'na soboj)
типа другие тут ни при чем..
lopata
cto znachit oastal'nye ne prichem? spasibo konechno volvo, potomu chto srazu ponyat' kak rabotayut Pointers i Listenochen' tyazhelo.
No on predpochel udalit'sya. i vryatli emu teper' nuzhno moe spasibo.
Lapp
Цитата(lopata @ 18.12.2009 12:31) *
No on predpochel udalit'sya. i vryatli emu teper' nuzhno moe spasibo.
А, вот оно как. Проявил нелояльность - и вышел из господской милости. Типа сам виноват. Ну-ну.

norespect.gif

М
[b]Просьба ознакомиться в Правилами Форума (ссылка вверху страницы). Особенно пункт 6.


lopata
ya ne o tom. mne nikto nichego ne obyazan. i pomogat' tozhe. No eto sdorovo kogda dejstvitelno pomogayut. Prosto tak. 
I mozhet eto moya vina chto volvo
Цитата
задания "по частям" не очень интересуют... Вернее, не интересуют вообще.

on yasno dal ponyat' " otvali" i poetomu dumayu emu moe spasibo ne nuzhno.
Lapp
Цитата(lopata @ 18.12.2009 12:53) *
on yasno dal ponyat' " otvali" i poetomu dumayu emu moe spasibo ne nuzhno.
"спасибо" говорят разве потому, что оно интересует? Ты рассматриваешь свое спасибо, как нечто нужное тому человеку, который тебе помог?.. Я думал, что спасибо говорят, потому что есть внутреннее желание и даже необходимость поблагодарить человека за помощь.. Что сказать спасибо - это потребность того, кто получил помощь. Я не прав? И потом, я не усмотрел в словах волво отказа от твоей благодарности.. я плохо смотрел?
Гость
я ему уже сказала спасибо.
а с тобой строить диалог бесполезно. Так как ты сразу же негативно настроен. И сам у себя в голове сделал какой-то вывод.
всего хорошего.
Гость
P.S. "Сережа молодец"
Lapp
Цитата(Гость @ 18.12.2009 19:59) *
P.S. "Сережа молодец"
Что это означает? какой Сережа? зачем тут этот флуд?

lopata, ты снова утратил пароль? нужно восстанавливать?
lopata
Я к тому что : Сережа молодец - (потому что)Сережа мой сыночек(с)
Так и ты..принял четкую позицию.: кто молодец , а кто нет.
Я у меня указан женский пол. Обращайся пожалуйста корректно.
Цитата
lopata, ты снова утратил пароль?
Lapp
Цитата(lopata @ 19.12.2009 3:59) *
Я к тому что : Сережа молодец - (потому что)Сережа мой сыночек(с)
Так и ты..принял четкую позицию.: кто молодец , а кто нет.
Угу, конечно. Давай лезть дальше в бутылку..
Я тебе на будущее говорю: благодарность или хотя бы простая вежливость всегда были и будут в чести, поверь. А там уж можешь фантазировать и перекрашивать белое в черное, сколько тебе угодно - ищи моих сыночков, внучечков и т.д. и т.п., флаг тебе в руки.

Цитата
Я у меня указан женский пол. Обращайся пожалуйста корректно.
Дык - опечатка! Бывает же, да?.. Кстати, очень интересно построена фраза: как будто сначала было написано "я женского полу", а потом была предпринята не совсем удачная попытка переделать на более соответствующее истине "у меня указан женский пол" - так, наблюдение с рассуждением о природе вещей..

А обращаться теперь предпочту на "вы" - если придется (по долгу, чего вам не рекомендую). Так меньше вероятность опечаток..
Будьте здоровы, ваша заносчивость.

P.S.
нынешний КВН sucks
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.