Форум программистов, компьютерный форум, киберфорум
Pascal ABC
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.53/34: Рейтинг темы: голосов - 34, средняя оценка - 4.53
0 / 0 / 0
Регистрация: 16.10.2013
Сообщений: 12
1

Обратная польская запись

12.12.2015, 21:35. Показов 6556. Ответов 1
Метки нет (Все метки)

Требуется преобразовать выражение в обратную польскую запись и посчитать.

Программа вроде как почти готова, но не считаются выражения с унарным минусом. Как это исправить?
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
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
const
    op1=['+','-'];
    op2=['*','/'];
    ops= ['+', '-', '*', '/'];
    symb=['a'..'z','A'..'Z','0'..'9','.'];
    numb=['0'..'9'];
var
 
    sym :char;
    so,si,so1,q:string;
    p :word;
    i,k,error:integer;
    d,a,b,c:real;
    stack:array [1..100] of string;
procedure getsym;
begin
{perevod v opz}
    while (p<=length(si))and(si[p] in [#32, #9]) do
        inc(p);
    if p>length(si) then
        sym:=#0
    else
    begin
        sym:=si[p];
        inc(p)
    end;
end;
procedure expression;
forward;
procedure get_var;
begin
    so:=so+#32;
    while sym in symb do
    begin
        so:=so+sym;
        getsym
    end
end;
procedure term;
var a1:char;
begin
    if sym='(' then
    begin
        getsym;
        expression;
        getsym
    end
        else
        get_var;
    while sym in op2 do
    begin
        a1:=sym;
        getsym;
        term;
        so:=so+#32+a1
    end
end;
procedure expression;
var a1:char;
begin
    if sym='+' then
        getsym
    else if sym='-' then
    begin
        a1:='-';getsym
    end
        else
        a1:=#32;
    term;
    if a1='-' then so:=so+' (-)';
    while sym in op1 do
    begin
        a1:=sym;
        getsym;
        term;
        so:=so+#32+a1
    end
end;
begin
    si:='-3-4*4-4';
    so:=#32;
    p:=1;
    getsym;
    expression;
 
    writeln('Dano: ',si);
    writeln('OPZ: ',so);
 
{vichislenie v opz}
for i:=1 to length(so) do
if so[i] in numb then
 begin
  so1:=so1+so[i];
  so[i]:=' ';
 end
  else
if(so[i]=' ')and(length(so1)>0) then
 begin
  inc(k);
  stack[k]:=so1;
  so1:='';
 end
  else
if (so[i]='(') and(so[i+1]='-') then
 begin
  val(stack[k],c,error);
  c:=0-c;
  str(c,q);
  stack[k]:=q;
 end
 else
if so[i]in ops then
 begin
 {-------}
val(stack[k-1],a,error);
val(stack[k],b,error);
 {-------}
case so[i] of
'+': d:=a+b;
'-': d:=a-b;
'*': d:=a*b;
'/': d:=a/b;
end;
stack[k]:='';
dec(k);
str(d,stack[k]);
 end;
 
val(stack[k],d,error);
Writeln('Result: ',d);
end.
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.12.2015, 21:35
Ответы с готовыми решениями:

Польская инверсионная запись
Необходимо решить задачу вычисления значения выражения заданного в ПОЛИЗ, при следующих...

Разобраться в комментариях. Польская запись
Ребята! Помогите разобраться с комментариями. Запутался :( Uses CRT; {Вычисление значения...

Обратная польская запись
Можете подсказать алгоритм по переводу выражения из постфиксной нотации в инфиксную?

Обратная польская запись
Помогите написать программу для вычисления обратной польской записи, использовав стек. Например,...

1
133 / 148 / 64
Регистрация: 27.06.2013
Сообщений: 532
06.08.2016, 10:53 2
В программе вводится формула, представляющая из себя набор целых чисел и знаков арифметических действий +, -, *, /. Для изменения порядка действий используются круглые скобки.
Алгоритм преобразования. Очищаются поля: магазин и выходное поле. Анализируются поочередно все члены формулы. Числа отправляются в выходное поле в конец за имеющимися там данными. Знаки отправляются в магазин в конец за имеющимися там данными, при этом знак "+" или "-" выталкивает в выходное поле все знаки из магазина, пока не будет очищен магазин или не встретится открывающая скобка, а знак "*" или "/" выталкивает в выходное поле все знаки из магазина, пока не будет очищен магазин или не встретится один из знаков "+", "-", "(". Открывающая скобка отправляется в магазин. Закрывающая скобка выталкивает в выходное поле все знаки, пока не встретится открывающая скобка, затем уничтожает открывающую скобку и себя.
Порядок вычислений на основании обратной польской записи неоднократно описан.
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
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
uses crt;
const
n=50;
type mas=array[1..n] of string;
var mag,vixp:mas;
f,fv:string;
smv:char;
rez:real;
ch,L,i,j, k:integer;
begin
  ch:=0;
  write('Введите формулу: ');
  readln(f);
  If Copy(f, 1, 1) ='-' Then f:=concat('0',f);
  L:=Length(f);
  j:=0;
  k:=0;
  For i:=1 To L do
    begin
    smv:=f[i];
    If (smv >='0') And (smv <='9') Then
      begin
        ch:= ch * 10 +StrToInt(smv);
        If i = L Then
          begin
            k:= k + 1;
            vixp[k]:= IntToStr(ch);
          end;
          If (i < L) And ((Copy(f, i + 1, 1) < '0') Or (Copy(f, i + 1, 1) > '9')) Then
            begin
              k:= k + 1;
              vixp[k]:= IntToStr(ch);
            end;
      end
      Else
      If smv = '(' Then
        begin
          j:= j + 1;
          mag[j]:= smv;
          ch:= 0;
        end
        Else
        If smv =  ')' Then
          begin
            while j=j Do
              begin
                If j = 0 Then
                  begin
                    Writeln(concat('Некорректная формула! ',f,' Нажмите Enter'));
                    Readln;
                    halt;
                  End;
                  If mag[j] = '(' Then
                    begin
                      j:= j - 1;
                      ch:= 0;
                      break;
                    End;
                    k:= k + 1;
                    vixp[k]:= mag[j];
                    j:= j - 1;
              end;
          end
          Else
          If (smv = '+') Or (smv = '-') Then
            begin
              While j=j Do
                begin
                  If j = 0 Then
                    begin
                      j:= j + 1;
                      mag[j]:= smv;
                      ch:= 0;
                      break;
                    End;
                    If mag[j] = '(' Then
                    begin
                      j:= j + 1;
                      mag[j]:= smv;
                      ch:= 0;
                      break;
                    End;
                    k:= k + 1;
                    vixp[k]:= mag[j];
                    j:= j - 1;
                end;
            end
            Else
            If (smv = '*') Or (smv = '/') Then
              begin
                while j=j Do
                  begin
                    If j = 0 Then
                      begin
                        j:= j + 1;
                        mag[j]:= smv;
                        ch:= 0;
                        break;
                      End;
                      If (mag[j] = '(') Or (mag[j] = '+') Or (mag[j] = '-') Then
                      begin
                        j:= j + 1;
                        mag[j]:= smv;
                        ch:= 0;
                        break;
                      End;
                      k:= k + 1;
                      vixp[k]:= mag[j];
                      j:= j - 1;
                  end;
              end
              Else
              begin
                fv:=IntToStr(i);
                writeln(concat('Недопустимый символ ',fv,' в формуле! ',f,' Нажмите Enter'));
                readln;
                halt;
              End;
    End;
If j <> 0 Then
  begin
    For i:= j Downto 1 Do
      begin
        k:= k + 1;
        vixp[k]:= mag[i];
      end;
  End;
fv:= '';
For i:= 1 To k do
fv:= concat(fv,vixp[i],' ');
j:= 0;
For i:= 1 To k do
  Begin
    If (vixp[i] <> '+') And (vixp[i] <> '-') And (vixp[i] <> '*') And (vixp[i] <> '/') Then
      begin
        j:= j + 1;
        mag[j]:= vixp[i];
      end
      Else
       begin
       If j = 1 Then
         begin
           Writeln(concat('Некорректная формула! ',f,' Нажмите Enter'));
           Readln;
           halt;
         End;
       End;
    If vixp[i] = '+' Then
      begin
        mag[j - 1]:= FloatToStr(StrToFloat(mag[j - 1]) + StrToFloat(mag[j]));
        j:= j - 1;
      End;
    If vixp[i] = '-' Then
      begin
        mag[j - 1]:= FloatToStr(StrToFloat(mag[j - 1]) - StrToFloat(mag[j]));
        j:= j - 1;
      End;
    If vixp[i] = '*' Then
      begin
        mag[j - 1]:= FloatToStr(StrToFloat(mag[j - 1]) * StrToFloat(mag[j]));
        j:= j - 1;
      End;
    If vixp[i] = '/' Then
      begin
        mag[j - 1]:= FloatToStr(StrToFloat(mag[j - 1]) / StrToFloat(mag[j]));
        j:= j - 1;
      End;
    If vixp[i] = '(' Then
      begin
        Writeln(concat('Некорректная формула! ',f,' Нажмите Enter'));
        Readln;
        halt;
      End;
  end;
rez:= StrToFloat(mag[1]);
Writeln('Обратная польская нотация: ',fv);
Writeln('Результат: ', FloatToStr(rez));
writeln;
Write('Нажмите Enter');
readln;
end.
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.08.2016, 10:53

Обратная польская запись
программа не переводит выражение в обратную польскую запись list = input(&quot;Введите выражение - ...

Обратная польская запись
Пожалуйста помогите, всю голову себе сломал. Задание: &quot;Обеспечить перевод инфиксного выражения в...

Обратная польская запись
Нужно создать класс с++ для вычисления обратной польской записи с помощь стека.

Обратная польская запись
Пишу калькулятор для Android, все работает как надо но из строки сделать вычисление не получается,...


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

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.