Advertisement
lithie_oce

AISD_ReversePolishNotation

Apr 6th, 2024 (edited)
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 6.35 KB | Source Code | 0 0
  1. program PolishNotation;
  2.  
  3. {$APPTYPE CONSOLE}
  4.  
  5. {$R *.res}
  6.  
  7. uses
  8.     System.SysUtils;
  9.  
  10. Type
  11.     PStack = ^TStackNode;
  12.     TStackNode = Record
  13.         StackPriority: Integer;
  14.         Symbol: Char;
  15.         Prev: PStack;
  16.     End;
  17.  
  18. Const
  19.     CorrectSymbolsVar = ['a'..'z'];
  20.     CorrectSymbolsOper = ['*', '/', '-', '+', '^'];
  21.  
  22. Function InputStrExpr(): String;
  23. Var
  24.     StrExpr: String;
  25.     OpeningBracketCounter, ClosingBracketCounter, OperatorCount, VariableCount, I: Integer;
  26.     IsCorrect: Boolean;
  27. Begin
  28.     Repeat
  29.         Writeln('Введите выражение, состоящее из однобуквенных перемменных (от a до z), знаков арифметических операций и круглых скобок. Выражение должно соответствовать правилам математики.');
  30.         Readln(StrExpr);
  31.         OpeningBracketCounter := 0;
  32.         ClosingBracketCounter := 0;
  33.         IsCorrect := True;
  34.         if Length(StrExpr)<3 then
  35.             IsCorrect := False;
  36.         For I := 1 to Length(StrExpr) do
  37.         Begin
  38.             if IsCorrect And (StrExpr[I] In CorrectSymbolsVar) then
  39.             Begin
  40.                 if (I>1) And (StrExpr[I-1] In CorrectSymbolsVar) then
  41.                 Begin
  42.                     IsCorrect := False;
  43.                     Writeln('В записи выражения допущена математическая ошибка.');
  44.                 End;
  45.             End
  46.             Else
  47.                 if IsCorrect And (StrExpr[I] In CorrectSymbolsOper) then
  48.                 Begin
  49.                     if (I>1) And (StrExpr[I-1] In CorrectSymbolsOper) then
  50.                     Begin
  51.                         IsCorrect := False;
  52.                         Writeln('В записи выражения допущена математическая ошибка.');
  53.                     End;
  54.                 End
  55.                 Else
  56.                     if IsCorrect And (StrExpr[I] = '(') then
  57.                         Inc(OpeningBracketCounter)
  58.                     Else
  59.                         if IsCorrect And (StrExpr[I] = ')') then
  60.                             Inc(ClosingBracketCounter)
  61.                         Else
  62.                             if IsCorrect then
  63.                             Begin
  64.                                 Writeln('В выражении присутствуют недопустимые символы.');
  65.                                 IsCorrect := False;
  66.                             End;
  67.         End;
  68.         if OpeningBracketCounter<>ClosingBracketCounter then
  69.         Begin
  70.             Iscorrect := False;
  71.             Writeln('В записи выражения количество открывающих и закрывающих скобок не равны.');
  72.         End;
  73.     Until(IsCorrect);
  74.     InputStrExpr := StrExpr;
  75. End;
  76.  
  77. Procedure Output(Symbol:Char; StackTop: PStack; Const OutputString: String);
  78. Var
  79.     StackString: String;
  80. Begin
  81.     StackString := '';
  82.     While(StackTop^.Prev<>Nil) Do
  83.     Begin
  84.         StackString := StackTop^.Symbol + StackString;
  85.         StackTop := StackTop^.Prev;
  86.     End;
  87.     Writeln (Symbol,'                             ', StackString, '                                           ', OutputString);
  88. End;
  89.  
  90. Procedure CheckPriority(Var StackTop: PStack; RelativePriority: Integer; Symbol: Char; Var OutputString: String);
  91. Var
  92.     NewStackTop: PStack;
  93. Begin
  94.     while (StackTop^.Prev <> Nil) And (((Symbol <> ')') And (StackTop^.StackPriority >= RelativePriority)) Or ((Symbol = ')') And (StackTop^.Symbol <>'('))) do
  95.     Begin
  96.         if StackTop^.Symbol <> '(' then
  97.             OutputString := OutputString + StackTop^.Symbol;
  98.         NewStackTop := StackTop^.Prev;
  99.         Dispose(StackTop);
  100.         StackTop := NewStackTop;
  101.     End;
  102.     if Symbol <> ')' then
  103.     Begin
  104.         New(NewStackTop);
  105.         NewStackTop^.Symbol := Symbol;
  106.         if Symbol = '^' then
  107.             NewStackTop^.StackPriority := 5
  108.         Else
  109.             if Symbol = '(' then
  110.                 NewStackTop^.StackPriority := 0
  111.             Else
  112.                 NewStackTop^.StackPriority := RelativePriority+1;
  113.         NewStackTop^.Prev := StackTop;
  114.         StackTop := NewStackTop;
  115.     End
  116.     Else
  117.         if StackTop^.Symbol = '(' then
  118.         Begin
  119.             NewStackTop := StackTop^.Prev;
  120.             Dispose(StackTop);
  121.             StackTop := NewStackTop;
  122.         End;
  123.  
  124. End;
  125.  
  126. Function ConvertRevPolNot(Const StrExpr: String; Var StackTop: PStack): String;
  127. Var
  128.     I: Integer;
  129.     OutputString: String;
  130. Begin
  131.     OutputString := '';
  132.     for I := 1 to Length(StrExpr) do
  133.     Begin
  134.         case StrExpr[I] of
  135.             '+', '-': CheckPriority(StackTop, 1, StrExpr[I], OutputString);
  136.             '*', '/': CheckPriority(StackTop, 3, StrExpr[I], OutputString);
  137.             '^': CheckPriority(StackTop, 6, StrExpr[I], OutputString);
  138.             'a'..'z': CheckPriority(StackTop, 7, StrExpr[I], OutputString);
  139.             '(': CheckPriority(StackTop, 9, StrExpr[I], OutputString);
  140.             ')': CheckPriority(StackTop, 0, StrExpr[I], OutputString);
  141.         end;
  142.         Output(StrExpr[I], StackTop, OutputString);
  143.     End;
  144.     CheckPriority(StackTop, 0, ')', OutputString);
  145.     Output(' ', StackTop, OutputString);
  146.     ConvertRevPolNot := OutputString;
  147. End;
  148.  
  149. Function CalculateRang (Const RevPolNot: String): Integer;
  150. Var
  151.     OperatorCount, VariableCount, I: Integer;
  152. Begin
  153.     OperatorCount := 0;
  154.     VariableCount := 0;
  155.     For I := 1 to Length(RevPolNot) do
  156.     Begin
  157.         if (RevPolNot[I] In CorrectSymbolsVar) then
  158.             Inc(VariableCount)
  159.         Else
  160.             if (RevPolNot[I] In CorrectSymbolsOper) then
  161.                 Inc(OperatorCount);
  162.     End;
  163.     CalculateRang := VariableCount-OperatorCount;
  164. End;
  165.  
  166. Var
  167.     StrExpr, RevPolNot: String;
  168.     StackHead: PStack;
  169. begin
  170.     StrExpr := InputStrExpr();
  171.     New(StackHead);
  172.     Writeln('Символ                        Стек                                        Выходная строка');
  173.     RevPolNot := ConvertRevPolNot(StrExpr, StackHead);
  174.     Writeln('Выражение, записанное по обратной польской нотации:');
  175.     Writeln (RevPolNot);
  176.     Writeln('Ранг, полученной записи:');
  177.     Writeln(CalculateRang(RevPolNot));
  178.     Readln
  179. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement