Форум программистов, компьютерный форум, киберфорум
Pascal (Паскаль)
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.66/106: Рейтинг темы: голосов - 106, средняя оценка - 4.66
300 / 76 / 6
Регистрация: 23.11.2009
Сообщений: 25
1

Преобразование инфиксной записи в префиксную

09.01.2010, 14:52. Показов 20441. Ответов 3
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Преобразовать выражение в инфиксной форме в префиксную .Операнды представляют собой переменные с однобуквенным идентификатором или (и) цифры от 0 до 9, и в выражении используются только операции «+», «-», «*», «/». Реализовать с помощью стека.
Очень прошу помочь.

Добавлено через 16 минут
Реализация данной задачи есть в Delphi (а мне необходимо именно в Pascal, можно без дерева операций) :
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
unit Unit1;
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls;
 
const
  MAXPRIORITY=3; // больше любого из используемых приоритетов
  DIGITS=['0','1','2','3','4','5','6','7','8','9']; // цифры
  SIGNS=['+','-','*','/']; // знаки операций
 
type
  // ссылка на узел дерева выражения
  TreePtr = ^TreeNode;
  // узел дерева выражения
  TreeNode = record
    info: char;            // операнд или знак
    left, right: TreePtr; // ссылки на левое и правое поддеревья
  end;
  TfrmMain = class(TForm)
    Label1: TLabel;
    editExpression: TEdit;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    btnCalc: TButton;
    treeExpression: TTreeView;
    lblPrefix: TLabel;
    lblInfix: TLabel;
    lblPostfix: TLabel;
 
procedure btnCalcClick(Sender: TObject);
  private
    root: TreePtr; // корень дерева выражения
    // возвращает приоритет знака
    function Priority (sign: char): integer;
    // построение дерева выражения
    function BuildTree (str: string): TreePtr;
    // проверяет, верно ли составлено выражение
    function ExpressionIsRight (str: string): boolean;
    // отображаем дерево в памяти на компонент
    procedure ShowTree;
    procedure ShowTreeNode (node: TreePtr; visnode: TTreeNode);
    // обходы с записью выражения
    procedure LKPturn (node: TreePtr); // инфикс
    procedure LPKturn (node: TreePtr); // постфикс
    procedure KLPturn (node: TreePtr); // префикс
  public
    { Public declarations }
  end;
 
var
  frmMain: TfrmMain;
 
implementation
{$R *.dfm}
 
{-----------------------------------------
Функция возвращает приоритет арифметического знака
-----------------------------------------}
function TfrmMain.Priority (sign: char): integer;
begin
  case sign of
    '+','-': Priority:=0;
    '*','/': Priority:=1;
  end;
end;
 
{-----------------------------------------
Построение дерева выражения по строке, содержащей однозначные числа-операнды и
знаки арифметических операций (без скобок)
-----------------------------------------}
function TfrmMain.BuildTree (str: string): TreePtr;
var
  tmp: TreePtr;
  i: integer;
  priormin, imin: integer;
  leftstr, rightstr: string;
begin
  // остался всего один символ в строке и это
  // обязательно операнд
  if length(str)=1 then begin
    // создаем новый лист с этим операндом
    New(tmp);
    tmp^.info:=str[1];
    tmp^.left:=nil;
    tmp^.right:=nil;
    Result:=tmp;
  end
  // обрабатываем длинную строку
  else begin
    // находим самый правый знак с наименьшим приоритетом
    i:=length(str);
    priormin:=MAXPRIORITY; // заведомо больше любого
    imin:=i;
    while i>=1 do begin
      // нашли очередной минимум
      if ((str[i] in SIGNS)and(Priority(str[i])<priormin)) then begin
        priormin:=Priority(str[i]);
        imin:=i;
      end; // if
      i:=i-1;
    end; // while
    // создаем узел дерева с найденным знаком
    New(tmp);
    tmp^.info:=str[imin];
    // выделяем левую и правую подстроку относительно этого знака
    leftstr:=Copy(str,1,imin-1);
    rightstr:=Copy(str,imin+1,length(str)-imin);
    // строим поддерево по каждой подстроке
    tmp^.left:=BuildTree(leftstr);
    tmp^.right:=BuildTree(rightstr);
    Result:=tmp;
  end; // else
end;
 
{-----------------------------------------
Правильно ли выражение?
-----------------------------------------}
function TfrmMain.ExpressionIsRight(str: string): boolean;
var
  i: integer;
begin
  Result:=true;
  for i:=2 to length(str) do
    // нельзя, чтобы рядом стояло два знака или два числа
    if ((str[i] in SIGNS)and(str[i-1] in Signs))or
       ((str[i] in DIGITS)and(str[i-1] in DIGITS)) then
         Result:=FALSE;
end;
 
{-----------------------------------------
Сборка расчета: получаем строку выражения, строим дерево, показываем дерево,
показываем разные записи выражения
-----------------------------------------}
procedure TfrmMain.btnCalcClick(Sender: TObject);
begin
  if editExpression.Text='' then begin
    MessageDlg('Ошибка! Выражение не должно быть пустым', mtError, [mbOK], 0);
    exit;
  end;
  if not ExpressionIsRight(editExpression.Text) then begin
    MessageDlg('Ошибка! Выражение должно состоять из однозначных чисел и '+
               'знаков +, -, *, / и быть составлено правильно. Например, '+
               '5+3*7', mtError, [mbOK], 0);
    exit;
  end;
  // строим дерево выражения
  root := BuildTree(editExpression.Text);
  // показываем дерево
  ShowTree;
  // показываем выражения
  lblInfix.Caption := '';
  LKPturn (root);
  lblPrefix.Caption := '';
  KLPturn (root);
  lblPostfix.Caption := '';
  LPKturn (root);
end;
 
{-----------------------------------------
Отображаем дерево в памяти на компонент TTreeView
-----------------------------------------}
procedure TfrmMain.ShowTree;
var
  tmp: TreePtr;
  vistmp: TTreeNode;
begin
  TreeExpression.Items.Clear;
  // обход
  ShowTreeNode (root, nil);
end;
 
{-----------------------------------------
Обход: приделываем узлы к визуальному дереву
-----------------------------------------}
procedure TfrmMain.ShowTreeNode(node: TreePtr; visnode: TTreeNode);
begin
  if (node<>nil) then begin
    visnode := TreeExpression.Items.AddChild(visnode, node^.info);
    ShowTreeNode(node^.left, visnode);
    ShowTreeNode(node^.right, visnode);
  end;
end;
 
{-----------------------------------------
Вывод строки арифметического выражения в инфиксном виде: A+B (ЛКП-обход)
-----------------------------------------}
procedure TfrmMain.LKPturn (node: TreePtr);
begin
  if node<>nil then begin
    LKPturn(node^.left);
    lblInfix.Caption := lblInfix.Caption + node^.info;
    LKPturn(node^.right);
  end;
end;
 
{-----------------------------------------
Вывод строки арифметического выражения в префиксном виде: +АВ (КЛП-обход)
-----------------------------------------}
procedure TfrmMain.KLPturn(node: TreePtr);
begin
  if node<>nil then begin
    lblPrefix.Caption := lblPrefix.Caption + node^.info;
    KLPturn(node^.left);
    KLPturn(node^.right);
  end;
end;
 
{-----------------------------------------
Вывод строки арифметического выражения в постфиксном виде
(обратная польская запись): АВ+ (ЛПК-обход)
-----------------------------------------}
procedure TfrmMain.LPKturn(node: TreePtr);
begin
  if node<>nil then begin
    LPKturn(node^.left);
    LPKturn(node^.right);
    lblPostfix.Caption := lblPostfix.Caption + node^.info;
  end;
end;
 
end.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.01.2010, 14:52
Ответы с готовыми решениями:

Преобразование выражения из инфиксной формы в префиксную, используя списки
Напишите,пожалуйста, программу преобразования выражения из инфиксной формы в префиксную, используя...

Преобразование в постфиксную запись из инфиксной
Переводил код Python: from pythonds.basic.stack import Stack def infixToPostfix(infixexpr): ...

Преобразование арифметического выражения из инфиксной в постфиксную форму записи
Помогите реализовать алгоритм I-P на Pascal...Для работы со стеком использовать связное...

Выполнить преобразование записи в число
Пусть входной поток литер содержит по крайней мере одну цифру. Считая первую из них началом записи...

3
MrTi
23.05.2010, 15:23 2
Алгоритм вычисления постфиксной формы записи из инфиксной:
К формуле на входе (в конец записи) и на вершину стека добавляем остановочный оператор – %;
Поэлементно слева направо идем по формуле;
Операнды переходят в результат;
Левые круглые скобки толкаем(push) в стек;
Встретив правую круглую скобку, выталкиваем(pop) из стека все операторы пока не встретим левую скобку;
Если оператор имеет более высокий приоритет вычисления, чем оператор на вершине стека, то оператор толкаем в стек;
Если оператор имеет равный или меньший приоритет вычисления, чем оператор на вершине стека, то выталкиваем оператор из стека в результат, и толкаем в стек новый оператор;
Достигнув на входе % – остановочный оператор, выталкиваем все из стека, пока не дойдем до %.

Алгоритм вычисления префиксной формы записи реализуется следующим образом:

Имеем на входе формулу в инфиксной форме: a+b/(c-d);
Перепишем формулу справа налево: (d-c)/b+a;
Воспользуемся алгоритмом постфиксной трансляции, получим: dc-b/a+;
Полученную формулу перепишем справа налево, получим формулу в префиксной записи: +a/b-cd.

НАшел в сети. Может поможет!!!!
300 / 76 / 6
Регистрация: 23.11.2009
Сообщений: 25
23.05.2010, 17:56  [ТС] 3
Лучший ответ Сообщение было отмечено Светлана_1988 как решение

Решение

Может быть кому-нибудь понадобится вот сделала программу сама:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
program lab1;
 
uses crt;
 
type
 ptr=^stack;
 stack=record
 val:char;
 pnt:ptr;
end;
 
function prioritet(b:char):byte;
  begin
    if (b='*') or (b='/') then
      prioritet:=1
    else
      prioritet:=0;
  end;
 
function empty(r:ptr):boolean;
begin
 empty:=r=nil;
end;
 
procedure push(x:char; var r:ptr);
var
 p:ptr;
begin
 new(p);
 p^.val:=x;
 p^.pnt:=r;
 r:=p;
end;
 
function pop(var r:ptr):char;
var
 p:ptr;
begin
 p:=r;
 pop:=p^.val;
 r:=p^.pnt;
 dispose(p);
end;
 
function pup(var r:ptr):char;
begin
 pup:=r^.val;
end;
 
var
s1,s2:ptr;
n,i:byte;
a:string;
 
begin
  clrscr;
  writeln('Vvedite stroku');
  readln(a);
    for i:=length(a) downto 1 do
      begin
        if (i mod 2)<>0 then
          push(a[i],s1)
        else
          begin
            if not empty(s2) then
              if prioritet(a[i])<prioritet(pup(s2)) then
                  repeat
                    push(pop(s2),s1)
                  until not (prioritet(a[i])<prioritet(pup(s2))) or (empty(s2));
                push(a[i],s2);
          end;
      end;
  while not empty(s2) do
    push(pop(s2),s1);
  while not empty(s1) do
    write(pop(s1));
  readln;
end.
2
0 / 0 / 0
Регистрация: 28.10.2018
Сообщений: 15
30.04.2020, 01:44 4
Не хотелось бы обламывать всех читающих это, но при преобразовании в инфиксную форму выражения A+B+C+D вышеописанным способом мы получаем +A+B+CD хотя правильный вариант это +++ABCD. Короче данный способ работает не всегда не знаю почему так и на всех сайтах пишут что он рабочий,хотя и других способов я не нашёл...
0
30.04.2020, 01:44
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.04.2020, 01:44
Помогаю со студенческими работами здесь

Заменить постфиксную пеменную на префиксную
Помогите, срочно!!! Программа на Паскале: заменить постфиксную пеменную на префиксную

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

Перевод из инфиксной записи в постфиксную
Всем привет! Ребята, помогите пожалуйста решить задачу. Нужно написать программу с использованием...

Преобразование инфиксной записи арифметического выражения в префиксную
Доброго времени суток, ребята! Помогите с решением ЛР. Нужно используя только примитивы Lisp...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru