Форум 3DNews
Вернуться   Форум 3DNews > Программирование > Программирование

Ответ Создать новую тему
Опции темы Опции просмотра
Непрочитано 16.06.2006, 15:18   [включить плавающее окно]   #1
Sergey_Sun
Мужской Интересующийся
Автор темы
 
Регистрация: 04.12.2004
Построение двоичного дерева. Нужна помощь.

Привет люди!!! Помогите разобраться в программке. Ее задача – построение двоичного дерева для заданного арифметического выражения. Т.е. пользователь вводит выражение, и оно представляется в памяти в виде двоичного дерева.
Добавьте пож-та комментарии к указанным строчкам и поправьте мои, если необходимо. Буду очень благодарен.
Код программы:

type
TOperandStyle = (osNumber, osExpression); {что это и для чего?}

TOperand = class
private
FStyle: TOperandStyle; // что это за поле, для чего используется?
FValue: Extended; // что за поле, для чего?
FOperand1: TOperand; // это я так понял левое поддерево
FOperand2: TOperand; // правое поддерево
FAction: Char; {операция (+ - * / ) }
protected
function GetValue(): Extended;
{метод GetValue для чтения, но почему именно в pretected?}
public
property Value: Extended read GetValue write FValue;
{ создание свойства Value с методом чтения GetValue и методом записи FValue }

constructor Create(Expression: string); {конструктор выделяет память для объекта, Expression – это поле для выражения}

destructor Destroy(); override;
{освобождение памяти, но что такое override?}

end;

{ TOperand }

function TOperand.Getvalue(): Extended;
begin
if FStyle = osNumber then
Result := FValue
{для чего?}
else
case FAction of
'+': Result := FOperand1.Value + FOperand2.Value;
'-': Result := FOperand1.Value - FOperand2.Value;
'*': Result := FOperand1.Value * FOperand2.Value;
'/': Result := FOperand1.Value / FOperand2.Value;
{арифметические операции}

else
raise Exception.Create('Unknown action.'); {это что такое? что такое raise? }
end;
end;


constructor TOperand.Create(Expression: string);
var
Index: Integer;
{длина выражения}
BracketCount: Integer;
{если знак + или – вне скобок, BracketCount=0}
OperandExpression1, OperandExpression2: string;
{для чего?}
PassNumber: Integer;
{номер прохода: PassNumber=1, если идет + - , PassNumber=2, если * /}
Completed : Boolean;
{разбор выражения закончен, если Completed=true}
begin
inherited Create();
{ директива inherited вызывает конструктор родительского класса, зачем оно тут? }

FStyle := osNumber;
{что это, зачем?}
Expression := Trim(Expression);
{удаление пробелов}

if Expression[1] = '(' then
if Pos(')', Expression) = Length(Expression) then
Expression := Copy(Expression, 2, Length(Expression) - 2);
{если в начала выражения открывающаяся скобка и если закрывающаяся скобка в конце выражения – тогда копируем в Expression выражение без скобок. Внимание вопрос: почему Length(Expression)-2, а не Length(Expression)-1? }

Completed := False; {дерево не построено}
PassNumber := 1;

while (PassNumber <= 2) and not Completed do
begin
BracketCount := 0;
OperandExpression1 := '';
OperandExpression2 := '';
Index := Length(Expression);
{В Index заносим количество символов выражения}

while (Index > 0) and not Completed do
{пока длина выражения больше нуля и дерево не построено}
begin

case Expression[Index] of
')':
begin
Inc(BracketCount);
end;
{если в выражении есть закрывающаяся скобка, то увеличиваем BracketCount на единицу}

'(':
begin
Dec(BracketCount);
end;
{если в выражении есть открывающаяся скобка, то уменьшаем BracketCount на единицу}

'+', '-', '*', '/':
if (BracketCount = 0)
and ((Expression[Index] in ['+', '-']) or (PassNumber = 2)) then
{если в выражении есть + , - , * , / и если BracketCount равен нулю(т.е. количество закрывающихся и открывающихся скобок совпадает) и (зачем нужно Expression[Index] in ['+', '-']) или PassNumber равен 2}
begin
FStyle := osExpression;
{что и зачем?}
FOperand2 := TOperand.Create(OperandExpression2);
{строим правое поддерево: (а что создается то и как?) }
OperandExpression1 := Copy(Expression, 1, Index - 1);
{ Почему Index-1? }
FOperand1 := TOperand.Create(OperandExpression1);
{ строим левое поддерево: (что создается и как?}
FAction := Expression[Index];
{Заносим символ в FAction. Зачем?}
Completed := True;
{Дерево построено}
end;

end;

OperandExpression2 := Expression[Index] + OperandExpression2;
{Что, зачем и почему? Ничего я не пойму…}
Dec(Index);
{уменьшаем количество символов на единицу}

end; // while Index < Length(s) do

Inc(PassNumber);
{увеличиваем на единицу номер прохода}
end;

if FStyle = osNumber then
{это тут что делает?}
begin
FValue := StrToFloat(Expression);
{Преобразуем строку в вещественное число (Expession – это один символ?) и заносим поле FValue}
end;

end;

destructor TOperand.Destroy(); {освобождение памяти}
begin
if Assigned(FOperand1) then
FOperand1.Destroy();
if Assigned(FOperand2) then
FOperand2.Destroy();
{что значит Assigned?}
inherited;
{ директива inherited вызывает конструктор родительского класса, зачем оно тут? }
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Operand: TOperand;
begin
Operand := TOperand.Create(Edit1.Text);

try
Edit2.Text := FloatToStr(Operand.Value);
except
on EZeroDivide do
begin
ShowMessage('На ноль делить нельзя!!!');
exit;
end;
{если при выполнении преобразования строки в вещественное число получится ошибка – вывести сообщение}

on EConvertError do
begin
ShowMessage(‘Нельзя вводить буквы!!!’);
exit;
end;
{а вот это сообщение почему-то не работает, выводит стандартное делфи-сообщение }

finally
{а вот тут не работает – показывает на finally и пишет: ‘end’ expected but ‘Finally’ found}
{что значит finally?}
Operand.Free();
{освобождение памяти}
end;
end;
__________________
Go to zeitgeistmovement.ru

Последний раз редактировалось Sergey_Sun; 16.06.2006 в 15:51.
Sergey_Sun вне форума  
Ответить с цитированием
Непрочитано 22.06.2006, 15:15   [включить плавающее окно]   #2
Phodopus
Мужской Продвинутый
 
Регистрация: 05.10.2005
Адрес: Санкт-Петербург
finally - блок инструкции try, который будет выполнен в независимости от успеха или неудачи выполнения основного блока (возникновения в нем исключения)
Phodopus вне форума  
Ответить с цитированием
Непрочитано 26.06.2006, 13:32   [включить плавающее окно]   #3
Andron_
Мужской Заслуженный
 
Аватар для Andron_
 
Регистрация: 01.02.2004
Адрес: Новосибирск
как-то не очень тянет разбираться в чьем-то коде...
__________________
Дилетант широкого профиля. По совместительству преподаватель С/С++.
Andron_ вне форума  
Конфигурация ПК
Ответить с цитированием
Ответ Создать новую тему

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Текущее время: 06:36. Часовой пояс GMT +3.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 2000-2017 3DNews. All Rights Reserved.
Администрация 3DNews требует соблюдения на форуме правил и законов РФ
Серверы размещены в Hostkey