IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Упростить дерево-формулу!
сообщение
Сообщение #1





Группа: Пользователи
Сообщений: 1
Пол: Мужской

Репутация: -  0  +


Формулу вида
<формула >::=<терминал >|(<формула ><знак><формула >)
<знак>::= + | – | * | /
<терминал >::=<переменная>|<цифра >
<переменная>::=a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z
<цифра >::=0|1|2|3|4|5|6|7|8|9
можно представить в виде двоичного дерева по следующим правилам:
формула из одного терминального символа (цифры или переменной )
представляется деревом, состоящим из одной вершины, содержащей этот
символ, а формула вида (f1 s f2) — деревом, в котором корень — это знак s, а
левое и правое поддеревья — это соответствующие представления формул
f1 и f2. О писать подпрограмму, которая:
преобразует дерево-формулу, заменяя в нем все поддеревья,
соответствующие формулам ((f1 +- f2) * f3) и (f1 * (f2 + - f3)), на поддеревья,
соответствующие формулам ((f1 * f3) +-(f2 * f3)) и ((f1 * f2) +-(f1 * f3));

есть несколько готовых методов:
модуль создания корня дерева, здесь функция создания узла

unit UParentKnot;

interface


type
PNode = ^TNode;
TNode = object
private
FLeft,
FRight: PNode;

public

constructor InitEmpty;

Procedure Print; virtual;

function LoadFromStr (var str : string ; var i : integer) : boolean; virtual;
Procedure SaveToText(var F: Text); virtual;

{-}function Calculate: real; virtual;

procedure Clear;
destructor done; virtual;

Function GetLeft: PNode;
Function GetRight: PNode;

procedure SetLeft(ANode : PNode);
procedure SetRight(ANode : PNode);


end;

function NewNode (var str : string; var i : integer): PNode;


implementation

uses
SysUtils,
UIntKnot,
UVarNameKnot,
USignKnot;

function NewNode(var str: string; var i: integer): PNode;
begin
While (i<=Length(str)) and (str[i]=' ') do
inc(i);
if i>Length(str)
then Result:=nil
else
begin
case str[i] of
'0','1'..'9': Result:=New(PIntNode, InitEmpty);
'a'..'z': Result:=New(PVarNode, InitEmpty);
'(': Result:=New(PSignNode, InitEmpty);
else Result:=nil
end;
if Result<> nil
then
if not result.LoadFromStr(str,i)
then
begin
dispose(Result);
Result:=nil;
end;
end;
end;


добавление числа в дерево

uses
UParentKnot, SysUtils;

type
TElem = integer;
PIntNode = ^TIntNode;
TIntNode = object(TNode)
private
FInf: TElem;

public
constructor InitEmpty;
constructor Init(AInf: TElem);

procedure Input; virtual;
procedure Print; virtual;

function LoadFromStr (var str : string ; var i : integer) : boolean; virtual;
Procedure SaveToText(var f: TextFile); virtual;

{-}function Calculate: real; virtual;

Function GetInf: TElem;
Procedure SetInf(AInf: TElem);

end;



добавление переменной в дерево

TElem = string;
PVarNode = ^TVarNode;
TVarNode = object(TNode)
private
FInf: TElem;

public
Constructor InitEmpty;
constructor Init(AInf: TElem);

procedure Input; virtual;
procedure Print; virtual;

function LoadFromStr (var str : string ; var i : integer) : boolean; virtual;
Procedure SaveToText(var F: TextFile); virtual;

function Calculate: real; virtual;

Function GetInf: TElem;
Procedure SetInf(AInf: TElem);
end; {object}



добавление знака в дерево

type
TSign = (add,subtr,mult,divide,empty);
TElem = TSign;
PSignNode = ^TSignNode;
TSignNode = object (TNode)
private
FInf: TElem;
public

constructor InitEmpty;
constructor Init(AInf: TElem);

Procedure Input; virtual;
procedure Print; virtual;

function LoadFromStr (var str : string ; var i : integer) : boolean; virtual;
Procedure SaveToText(var f: TextFile); Virtual;

function Calculate: real; virtual;

Function GetInf: TElem;
Procedure SetInf(AInf: TElem);
end;{object}

const
NameSign: array [TSign] of char = ('+', '-', '*', '/', '?');

procedure ReadSign (var Sign: TSign);
function StrToSign(ch:char):TSign;



И, собственно, загрузка формулы из файла

Type
TFormula = object
Private
FRoot: PNode;

Public
constructor Init;

Procedure LoadFromText(FName: string);
Function LoadFromStr(str: string): boolean;

Procedure SaveToText (FName: string);
Procedure Print;

Function Calculate: real;

Procedure Clear;
end;


function TIntNode.LoadFromStr (var str : string ; var i : integer) : boolean;
var d: string;
begin
d:='';
While (i<=length(str)) and (str[i] in ['0'..'9']) do
begin
d:=d+str[i];
inc(i);
end;
FInf:=StrToInt(d);
Result:=true;
end;


function TVarNode.LoadFromStr (var str : string ; var i : integer) : boolean;
var c: string;
begin
c:='';
While (i<=length(str))and(str[i] in ['a'..'z']) do
begin
c:=c+str[i];
inc(i);
end;
FInf:=c;
VarMas.Add(FInf);
Result:=true;
end;

function TSignNode.LoadFromStr (var str : string ; var i : integer) : boolean;
begin
Result:=true;
if (i>Length(str)) then
Result:=false
else
if str[i]<>'(' then
Result:=false
else
begin
i:=i+1;
While (i<=Length(str)) and (str[i]=' ') do
inc(i);
SetLeft(NewNode(str,i));
if GetLeft=nil
Then result:=false
else
begin
While (i<=Length(str)) and (str[i]=' ') do
inc(i);
if (i>Length(str)) or not (Str[i] in ['+','-','*','/']) then
Result:=false
else
begin
FInf:=StrToSign(Str[i]);
i:=i+1;
While (i<=Length(str)) and (str[i]=' ') do
inc(i);
SetRight(NewNode(str,i));
if GetRight=nil then
Result:=false
else
begin
While (i<=Length(str)) and (str[i]=' ') do
inc(i);
if (i>Length(str)) or (str[i]<>')') then
Result:=false
else
i:=i+1;
end;
end
end;
end;
end;

Procedure TFormula.LoadFromText(FName: string);
var
F: Text;
s, str: string;
begin
AssignFile(F,FName);
reset(f);
str:='';
while not eof(f) do
begin
readln(f, s);
str:=str+s
end;
close(f);
if not LoadFromStr(str)
then writeln;
end;



Помогите пожалуйста дописать нехватающие методы и оформить задачу. Заранее спасибо, кто поможет

Сообщение отредактировано: Веталь -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Тему скрыл временно, до 1-го мая. Топикстартер уведомлен в PM.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Гость






Ну, в общем, тема открыта даже раньше, чем я говорил. Итак, по порядку:

1) я не знаю, зачем ты привел здесь эти куски программы, они ничего не дают. Либо надо было приводить только структуру классов, либо - программу, строящую дерево разбора полностью. Третьего не дано. Я не думаю, что кто-то будет подгонять программу, чтобы она легла точно на описания классов, которые привел ты. Тем более, что ты явно что-то перемудрил, все делается гораздо проще...

2) теперь о том, как это - "проще". Вот так:

Запусти программу и посмотри на результаты ее работы. Она сначала строит дерево разбора для приведенного выражения и вычисляет его, а потом
Цитата
преобразует дерево-формулу, заменяя в нем все поддеревья,
соответствующие формулам ((f1 +- f2) * f3) и (f1 * (f2 + - f3)), на поддеревья,
соответствующие формулам ((f1 * f3) +-(f2 * f3)) и ((f1 * f2) +-(f1 * f3));
и снова вычисляет значение выражения. При правильной замене значение всего выражения должно остаться неизменным. Смотри, разбирайся. Это можно было бы еще немного укоротить, но я этого делать не стал, боюсь, скажется на читабельности. Если разберешься в алгоритме создания дерева и замены поддеревьев, с легкостью сократишь программу самостоятельно... Пробуй smile.gif


Прикрепленные файлы
Прикрепленный файл  expr.zip ( 1.78 килобайт ) Кол-во скачиваний: 262
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






спасибо, буду разбираться smile.gif
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 19.04.2024 19:37
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name