Palpalich
15 Dec 2008, 13:15
помогите пожалуйста решить задачу на паскале:
Составить программу вычисления суммы всех ключей дерева.
я прогу написал, чтобы она формировала и выводило дерево, а посчитать ключи на могу...
прога:
program derevo;
uses crt;
Type inform = integer; {тип информационного поля}
ss = ^zveno;
zveno = record
key: integer;
inf: inform;
left, right: ss;
end;
Procedure vstavka(var p: ss; k: integer);
Begin
If p = nil then
Begin
New(p); p^.key:=k; p^.left:=nil; p^.right:=nil;
End
Else
If k < p^.key then vstavka(p^.left, k);
If k > p^.key then vstavka(p^.right, k);
End;
Procedure print(var p: ss; h: integer);
Var i: integer;
Begin
If p <> nil then
Begin
Print(p^.right, h + 4);
For i:=1 to h do write(' ');
Writeln(p^.key);
Print(p^.left, h + 4);
End
End;
Procedure ch( n, s: integer);
Var i: integer; p: ss; d:integer;
Begin
If p <> nil then begin
for i:=1 to n do
s:=p^.inf+s;
writeln(s);
end;end;
var t:ss;n,c,f,i,y:integer;
begin clrscr;
writeln('vvedite kolichestvo kluchey dereva');
readln(n);
writeln('vvedite kluchi dereva');
for i:=1 to n do
begin
read©;
vstavka(t,c);
end;
print(t,c);
ch(f,n);
readkey; end.
подскажите как подсчитать ключи....
Надо реализовать какой нить обход дерева.
Palpalich
16 Dec 2008, 16:42
дак я и не знаю как это организовать...
Tervyn
16 Dec 2008, 17:25
Ты уже сделал обход дерева при выводе ключей

Подсчет суммы ведется аналогично. Например так:
Код
function CalcKeySumm(Tree: SS): Integer;
begin
if Tree = nil then
begin
CalcKeySumm := 0;
end else
begin
CalcKeySumm := Tree^.Key + CalcKeySumm(Tree^.Left) + CalcKeySumm(Tree^.Right);
end;
end;
От того в каком порядке стоят слагаемые обход дерева называется левосторонним, и т.д.
Palpalich
17 Dec 2008, 13:32
спасибо огроменное, всё работает!!! слушай, дак это получается рекурсивная функция, правильно? и конечным результатом будет дерево??(Tree: SS)
Функция рекурсивная, но можно обойтись и без рекурсии.
Palpalich
17 Dec 2008, 14:46
как тогда организовать обход дерева, и что на выходе?
Цитата(Palpalich @ 17 Dec 2008, 13:32)
спасибо огроменное, всё работает!!! слушай, дак это получается рекурсивная функция, правильно? и конечным результатом будет дерево??(Tree: SS)
Конечным результатом у функции будет целочисленное число - там же указанно
function CalcKeySumm(Tree: SS):
Integer;
Palpalich
17 Dec 2008, 18:03
дак (Tree: SS) - это ссылочный тип данных...
Добавлено ([mergetime]1229526216[/mergetime]):
помогите регить ещё одну задачу please:):
Дан текст (в текстовом файле). В дереве, построенном из слов текста определить количество вершин дерева, содержащих слова, являющиеся палиндромами.
Примечание. Тип элемента в узле дерева (String), кроме того, необходимо ввести счетчик числа повторений каждого слова.
Функция берет дерево - возвращает целое число.Почему результат по твоему должен быть деревом?
Tervyn
17 Dec 2008, 19:38
Цитата(Palpalich @ 17 Dec 2008, 13:32)
спасибо огроменное, всё работает!!! слушай, дак это получается рекурсивная функция, правильно? и конечным результатом будет дерево??(Tree: SS)
Результатом будет число, ведь функция возвращает число. Параметр функции Tree: SS это дерево чьи ключи надо считать, а сам ключ - целое число. Для дерева вида
2
1 3
обход и резултат будет таким:
при вызове с вершиной 2 сумма 2 + результат рекурсии с вершинами 1 и 3
при вызове с вершиной 1 сумма 3 + результат рекурсии с вершинами из вершины 1. Так как таких вершин нет функция вернут 0
Для вершины 3 аналогично.
В итоге получаем сумму 2 + 1 + 0 + 0 + 3 + 0 + 0
Цитата(Монца @ 17 Dec 2008, 14:34)
Функция рекурсивная, но можно обойтись и без рекурсии.
Цитата(Palpalich @ 17 Dec 2008, 14:46)
как тогда организовать обход дерева, и что на выходе?
Можно, но в данном случае врядли. Обход дерева подразумевает возможность возврата в предыдущую вершину. То есть для примера выше из 2 мы должны просмотреть ветку начинающуюся с 1, вернуться, затем ветку с 3. Возможность возврата добавляется введением ссылку на вершину выше. Тип узла дерева должен выглядить как-то так:
type
PTree = ^TTree;
TTree = record
Info: Integer;
Left, Right: PTree;
Owner: PTree;
end;
Для примера выше для вершины 2 поле Owner = nil, для вершин 1 и 3 - ссылка на вершину 2
Ну а про палиндромы можно сделать например так:
Код
type
PTree = ^TTree;
TTree = record
Info: string;
Count: Integer;
Left,
Right: PTree;
end;
{ Функция добавления слова в дерево }
{ Если делать эту функцию рекурсивной и не принять мер }
{ то каждый раз при ее вызове строка будет дублироваться }
{ в стеке и произойдет переполнение стека. Хотя те }
{ компиляторы что поумнее передавать будут не строку, а }
{ указатель на строку. И переполнения не будет. Как }
{ BP не помню:( Ниже три варианта реализации этой функции }
{ Вариант добавления слова в дерево без рекурсии }
procedure AddItem(var ATree: PTree; AInfo: string);
function MakeItem(AInfo: string): PTree;
var
P: PTree;
begin
P := nil;
New(P);
if P <> nil then
begin
P^.Info := AInfo;
P^.Left := nil;
P^.Right := nil;
P^.Count := 1;
P^.Info := AInfo;
end;
MakeItem := P;
end;
var
P: PTree;
begin
if ATree = nil then
begin
ATree := MakeItem(AInfo);
Exit;
end;
P := ATree;
while P <> nil do
begin
if AInfo = P^.Info then
begin
P^.Count := P^.Count + 1;
Exit;
end;
if AInfo < P^.Info then
begin
if P^.Left = nil then
begin
P^.Left := MakeItem(AInfo);
Exit;
end else
begin
P := P^.Left;
Continue;
end;
end;
if AInfo > P^.Info then
begin
if P^.Right = nil then
begin
P^.Right := MakeItem(AInfo);
Exit;
end else
begin
P := P^.Right;
Continue;
end;
end;
end;
end;
{ Вариант добавления слова в дерево с рекурсией }
{ Внешняя функция является как оболочкой для }
{ реальной функции. Реальная же не передает строку, }
{ а пользуется строкой-параметром оболочки. Сколько }
{ бы раз не вызывалась реальная функция строка не }
{ передается и переполнения стека не будет }
procedure AddItem(var ATree: PTree; AInfo: string);
procedure Add(var ATree: PTree);
begin
if ATree = nil then
begin
New(ATree);
if ATree <> nil then
begin
ATree^.Info := AInfo;
ATree^.Count := 1;
ATree^.Left := nil;
ATree^.Count := nil;
end;
Exit;
end;
if ATree^.Info = AInfo then
begin
ATree^.Count := ATree^.Count + 1;
Exit;
end;
if AInfo < ATree^.Info then
Add(ATree^.Left)
else
Add(ATree^.Right);
end;
begin
Add(ATree);
end;
{ Вариант добавления слова в дерево с рекурсией }
{ Самый простой:) В списке параметров перед параметром }
{ AInfo ставим var. Тем самым мы гарантируем что }
{ передаваться будет не строка, а указатель на нее }
{ По крайней мере так задумано... }
procedure AddItem(var ATree: PTree; var AInfo: string);
begin
if ATree = nil then
begin
New(ATree);
if ATree <> nil then
begin
ATree^.Info := AInfo;
ATree^.Count := 1;
ATree^.Left := nil;
ATree^.Count := nil;
end;
Exit;
end;
if ATree^.Info = AInfo then
begin
ATree^.Count := ATree^.Count + 1;
Exit;
end;
if AInfo < ATree^.Info then
AddItem(ATree^.Left, AInfo)
else
AddItem(ATree^.Right, AInfo);
end;
{ Функция проверки является ли слово палиндромом }
{ Палиндром это ведь когда слово читается слева }
{ направо так же как справа налево? }
function IsPalindrom(AWord: string): Boolean;
var
I: Integer;
begin
for I := 1 to Length(AWord) div 2 do
if AWord[i] <> AWord[Length(AWord) - I + 1] then
begin
IsPalindrom := False;
Exit;
end;
IsPalindrom := True;
end;
{ Собственно подсчет палиндромов }
function CalcPalindromCount(ATree: Ptree): Integer;
var
N: Integer;
begin
if ATree = nil then
begin
CalcPalindromCount := 0;
Exit;
end;
if IsPalindrom(ATree^.Info) then
N := ATree^.Count { если копии палиндромов не считать то N := 1 }
else
N := 0;
CalcPalindromCount := N + CalcPalindromCount(ATree^.Left)
+ CalcPalindromCount(ATree^.Right);
end;
{ Очистка дерева }
procedure Clear(var ATree: PTree);
begin
if ATree <> nil then
begin
Clear(ATree^.Left);
Clear(ATree^.Right);
Delete(ATree);
ATree := nil;
end;
end;
Смысл такой - в записи вводим поле для подсчета дублей слов. Это поле меняется при добавлении слова. Рекурсивный вызов функции с параметром строкой потенциально может вызвать ошибку переполнения стека, предложил три варианта решения этой проблемы. Перед началом работы переменную-указатель на дерево надо выставить в nil. После все работы с деревом вызвать Clear с аргументом переменной-указателем на дерево. Количество палиндромов выдает функция CalcPalindromCount:
X := CalcPalindromCount(Tree);
Чтение слов из файла сделай сам - я просто не очень хорошо помню как работают Read, ReadLn при работе с текстовым файла, а Паскаля у меня не стоит (все писал в блокноте)
Это где так людей калечат, заставляют на паскале деревья писать?
А чем дерево на Паскале хуже деревьев на других языках? И почему калечат?
Собственно я привык считать паскаль языком для первокурсников, а там только вводят в суть программирования, деревья появляются на втором курсе уже на C/C++, у нас начали со второго, но это лирическое отступление к деревьям отношения не имеющее, мне только интересно: это Вас на первом курсе заставляют писать деревья, или же вы до 2-го паскаль учите, вряд ли тут просят выполнить задание не для ВУЗа.
Ну с технической стороны отличается конечно цель, мне она непонятна, неужели надо написать дерево хоть как-нибудь, это похвально, но зачем?
gamecreator
22 Dec 2008, 22:47
Глоин, оказывается есть другой, нормальный паскаль. Вот про него Ангел и говорит
ребят пожалуйста помогите решить задачу. очень срочно надо:
- Составить программу, определяющую количество вершин к - того уровня дерева.
говорят что легкая но нихера не получается... заранее благодарен.
Мне тут за некомпетентность минус влепили, хочется сатисфакции и срача.
Расскажите, пожалуйста, какую глупость я сказал.
за пост 12.
Написание деревьев на паскале не более сложная задача, чем написание деревьев на C
Что Ангел уже и сказал
Не спорю, я с паскалем во втором семестре завязал, наоборот, говорю, что калечат, раз заставляют писать на этом языке, или я не понимаю задачи, о чем тоже написал.
И Ангел про сложность ничего не писал, удивился только тому что "калечат".
На Паскале писать ничуть не сложнее. Наоборот, чётче, стабильнее, яснее. То есть ваш ответ сугубо индивидуален.
Абсолютно согласен со всем сказаным, код на паскале значительно проще читать, селекторы "классов" смотрятся пусть и менее эстетично, зато чотче отделяют название представителя класса от "методов" (не знаю, бывают ли тут вообще методы, но если не бывает, то я полностью согласен, они смазывают линейность чтения программы), блоки кода не размазываются по странице, так как begin и end куда нагляднее отделяют их, чем {} в C, ну и благодоря этим факторам программы на паскале работают много стабильнее аналогов на других языках, и не надо забывать про быстродействие.
Стабильность и быстродействие достигаются безусловно не только перечисленными средствами, надо представлять себе, что популярность языка ведёт к ухудшению качества общей массы продуктов, по этой причине паскаль много обгоняет все другие языки, даже прямого конкурента Бейсик.
друзья я почти все сделал. не могу понять как считать количество вершин К-ого уровня. уже всяко пробовал... не получается...
Program derevo;
Uses Crt;
Type inform = Integer;
ss = ^zveno;
zveno = Record
key: Integer;
inf: Inform;
left, right: ss;
End;
Var t:ss;
n,c,i,k: Integer;
{----формирование дерева----}
Procedure Vstavka (Var p: ss; x: Integer);
Begin
If p = Nil Then
Begin
New (p);
p^.inf:=x;
p^.key:=1;
p^.left:=Nil;
p^.right:=Nil;
End;
If x<p^.inf Then Begin Vstavka (p^.left,x); End;
If x>p^.inf Then Begin Vstavka (p^.right,x); End;
End;
{----вывод дерева----}
Procedure Print (Var p: ss; h: Integer);
Var i: Integer;
Begin
If p <> Nil Then
Begin
Print(p^.right,h+4);
For i:=1 To h Do Write (' ');
Writeln (p^.inf);
Print (p^.left,h+4);
End;
End;
Begin ClrScr;
Writeln ('Введите количество ключей дерева: ');
Readln (n);
Writeln ('Введите информ часть дерева: ');
For i:=1 To n Do
Begin
Read ©;
Vstavka (t,c);
End;
Print (t,c);
Writeln ('Введите уровень: ');
Readln (n);
А че тут дальше не пойму как реализовать
Readkey;
End.
подскажите пожалуйста
gamecreator
26 Dec 2008, 20:50
что-то типа:
Код
подсчет в дереве А вершин уровня К:
если корень дерева не существует, то вернуть 0
если К=0, то вернуть 1
иначе вернуть (подсчет в левой ветке вершин уровня К-1)+(подсчет в правой ветке вершин уровня К-1)
Добавлено ([mergetime]1230313830[/mergetime]):
но таким способом нельзя считать вершины на уровне больше, емнип, 128
ну так я про вот эти подсчеты и спрашиваю. уже полдня сижу циклы мучаю а ничего не выходит
gamecreator
26 Dec 2008, 23:48
я тебе русским языком функцию написал. осталось в паскаль перевести
да я понял что ты русским написал. вот только подсчет в правом и левом поддеревьях уровня К-1 делаться должен через цикл. я не могу понять как он делается
gamecreator
26 Dec 2008, 23:59
обязательно через цикл? рекурсивно не подходит?
да я и рекурсивно пробовал. если у тебя получится то буду очень благодарен
gamecreator
27 Dec 2008, 00:25
выложи способы, которыми делал чтобы не было непоняток
да я бы с радостью. только если у меня не получалось я удалял... не подумал даже. дружище попробуй сделать. просто очень срочно надо... тот фрагмент проги который я выложил он у меня так и валяется. никаких вариантов не сохранил...
gamecreator
27 Dec 2008, 00:50
я почти не знаю паскаля. вот в си - пожалуйста. а в паскале я пас.
ну попробуй в си написать. я уж подумаю как в паскаль переделать
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.