Консультация № 182624
25.03.2011, 19:46
89.75 руб.
0 5 1
Здравствуйте уважаемые эксперты! Пожалуйста, ответьте на вопрос: Возможно ли добавить в этот калькулятор возможность построения дерева выражения или проще писать все с нуля? Если это возможно, покажите пожалуйста на примере этой программы как это осуществить. Проект был найден мною на просторах интернета, понравилось то, что код не сложный, и вроде бы разбор нормальный. С этой темой я пока знаком на уровне теории, что можете порекомендовать? Спасибо большое за внимание

Обсуждение

давно
Профессионал
304622
583
30.03.2011, 04:23
общий
это ответ
Здравствуйте, Мироненко Николай!

Otvet.rar (400.0 кб)

Возможно я не совсем правильно понял задачу. Я построил дерево выражения, используя уже имеющуюся польскую запись. Это действительно легко -- если, сообразить, что разбирать её надо с конца. (На то, чтобы это сообразить я вечер-то и потратил.) Дальше всё летит как по маслу -- польская запись изначально на это ориентирована. Если же надо строить дерево до польской записи (например, польскую запись делать по дереву), то это уже сложнее.

Кроме того, вы не указали, что собственно делать с деревом. Я не стал мудрить с его выводом на экран, а сделал простую и очевидную вещь: вычисление выражения по дереву.

И ещё одно. Уже поздно, и я не стал писать комментарии. Если надо скажи -- я потом в мини-форум все объяснения и комментарии дам.
давно
Профессионал
304622
583
30.03.2011, 10:49
общий
Собственно мои изменения в программу заключаются в этой вот процедуре:

Код:

procedure TForm1.MakeTree(PF:string;NN:integer);
var Tree:PTree;

var i:byte;

function MakeBranch(var PF:string):PTree;
var t:PTree;
begin
if PF[length(PF)]='x'
then begin
new(t);
t^.Oper:=#0;
t^.Number:=StrToFloat(StringGrid1.Cells[0,NN-1]) ;
dec(NN);
delete(PF,length(PF),1);
t^.Right:=nil;
t^.Left:=nil;
end
else begin
new(t);
t^.Oper:=PF[length(PF)];
t^.Number:=0;
delete(PF,length(PF),1);
t^.Right:=MakeBranch(PF);
t^.Left:=MakeBranch(PF);
end;
MakeBranch:=t;
end;

function EvalTree(t:PTree):real;
begin
if t^.Oper=#0
then EvalTree:=t^.Number
else case t^.Oper of
'+':EvalTree:=EvalTree(t^.Left)+EvalTree(t^.Right);
'-':EvalTree:=EvalTree(t^.Left)-EvalTree(t^.Right);
'*':EvalTree:=EvalTree(t^.Left)*+EvalTree(t^.Right);
'/':EvalTree:=EvalTree(t^.Left)/EvalTree(t^.Right);
end;

end;

procedure DelTree(t:PTree);
begin
if t<>nil
then begin
DelTree(t^.Left);
DelTree(t^.Right);
dispose(t);
end;
end;

begin
i:=0;
Tree:=MakeBranch(PF);
Label5.Caption:=FloatToStr(EvalTree(Tree));
DelTree(Tree);
end;




И ещё. Разбор исходного выражения был бы проще, если бы делался через рекурсию -- как в вышеприведённом коде. В твоей программе задаётся стек -- это, Мсобственно, и есть способ сделать аналог рекурсии в простом линейном цикле. Тогда как в обычной рекурсии вложенность как бы организуется "сама собой", через стек вызова процедур.
Неизвестный
31.03.2011, 18:51
общий
Адресаты:
Не могу оценку поставить т.к.
Возможность оценивания ответов временно отключена
давно
Профессионал
304622
583
01.04.2011, 03:08
общий
Не могу оценку поставить т.к.


Ничего. Свет клином на этом не сошелся.

Вопросов-то нет?
Неизвестный
01.04.2011, 12:20
общий
Адресаты:
Пока что нет
Форма ответа