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 килобайт ) Кол-во скачиваний: 298
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






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

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

 



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