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