前缀表达式是一种没有括号的算术表达式,与中缀表达式不同的是,其将运算符写在前面,操作数写在后面。为纪念其发明者波兰数学家Jan Lukasiewicz,前缀表达式也称为“波兰式”。例如,- 1 + 2 3,它等价于1-(2+3)。

中文名

前缀表达式

纪念

Jan Lukasiewicz

转换算法

构造一个运算符栈

运算符

直接入栈

基本释义

前缀表达式就是前序表达式,是一种是由波兰数学家扬·武卡谢维奇1920年引入的数学表达式方式。

例如,- 1 + 2 3,它等价于1-(2+3)。

注意事项

后缀表达式源自于前缀表达式,为了区分前缀和后缀表示,通常将后缀表示称为逆波兰表示;因前缀表示并不常用,所以有时也将后缀表示称为波兰表示。

运算优势

前缀表达式是一种十分有用的表达式,将中缀表达式转换为前缀表达式后,就可以只依靠出栈、入栈两种简单操作完全解决中缀表达式的全部运算。

例如,(a+b)*(c+d)转换为*,+,a,b,+,c,d。

后面的前缀表达式的运算方式为:如果当前字符(或字符串)为数字或变量,则压入栈内;如果是运算符,则将栈顶两个元素弹出栈外并作相应运算,再将结果压入栈内。当前缀表达式扫描结束时,栈里的就是中缀表达式运算的最终结果。对比中缀运算的步骤,不难发现前缀运算在计算机上的优势。

求值方法

对于一个前缀表达式的求值而言,首先要从右至左扫描表达式,从右边第一个字符开始判断,如果当前字符是数字则一直到数字串的末尾再记录下来,如果是运算符,则将右边离得最近的两个“数字串”作相应的运算,以此作为一个新的“数字串”并记录下来。一直扫描到表达式的最左端时,最后运算的值也就是表达式的值。例如,前缀表达式“- 1 + 2 3“的求值,扫描到3时,记录下这个数字串,扫描到2时,记录下这个数字串,当扫描到+时,将+右移做相邻两数字串的运算符,记为2+3,结果为5,记录下这个新数字串,并继续向左扫描,扫描到1时,记录下这个数字串,扫描到-时,将-右移做相邻两数字串的运算符,记为1-5,结果为-4,所以表达式的值为-4。

表达对照

中缀表达式转化为前缀表达式的例子:

a+b ---> +,a,b

a+(b-c) ---> +,a,-,b,c

a+(b-c)*d ---> +,a,*,-,b,c,d

a+1+3 ---> +,+,a,1,3

转换算法

(1) 首先构造一个运算符栈(也可放置括号),运算符(以括号为分界点)在栈内遵循越往栈顶优先级不降低的原则进行排列。

(2)从右至左扫描中缀表达式,从右边第一个字符开始判断:

如果当前字符是数字,则分析到数字串的结尾并将数字串直接输出。

如果是运算符,则比较优先级。如果当前运算符的优先级大于等于栈顶运算符的优先级(当栈顶是括号时,直接入栈),则将运算符直接入栈;否则将栈顶运算符出栈并输出,直到当前运算符的优先级大于等于栈顶运算符的优先级(当栈顶是括号时,直接入栈),再将当前运算符入栈。

如果是括号,则根据括号的方向进行处理。如果是右的括号,则直接入栈;否则,遇左括号前将所有的运算符全部出栈并输出,遇右括号后将左、向右的两括号一起出栈(并不输出)。

(3) 重复上述操作(2)直至扫描结束,将栈内剩余运算符全部出栈并输出,再逆缀输出字符串。中缀表达式也就转换为前缀表达式了。

实例分析

将中缀表达式“1+((2+3)*4)-5”转换为前缀表达式。

中缀表达式

前缀表达式

(栈尾)运算符栈(栈顶)

说明

5

5

5,是数字串直接输出

-

5

-

-,栈内无运算符,直接入栈

5

-)

),直接入栈

4

5 4

-)

4,是数字串直接输出

*

5 4

-)*

*,栈顶是括号,直接入栈

)

5 4

- ) * )

),直接入栈

3

5 4 3

- ) * )

3,是数字串直接输出

+

5 4 3

- ) * ) +

+,栈顶是括号,直接入栈

2

5 4 3 2

- ) * )+

2,是数字串直接输出

(

5 4 3 2+

- ) *

(,与栈里最后一个)抵消,并释放它们之间的+

(

5 4 3 2+*

-

(,方法与上类同,请参考下一目录

+

5 4 3 2+*

-+

+,优先级大于等于栈顶运算符,直接入栈

1

5 4 3 2+*1

-+

1,是数字串直接输出

5 4 3 2+*1+-

扫描结束,将栈内剩余运算符全部出栈并输出

- + 1 * + 2 3 4 5

逆缀输出字符串

符号处理

对运算符的具体处理方法如下:

):直接入栈

(:遇)前,将运算符全部出栈并输出;遇)后,将两括号一起删除①

+、-:1

*、/、%:2

^:3

编程转换

1

#include<stdio.h>

2

#include<stdlib.h>

3

#include<conio.h>

4

#include<math.h>

5

#include<string.h>

6

#define MaxSize 99

7

char calc[MaxSize],expr[MaxSize];

8

int i,t;

9

struct {

10

 char data[MaxSize];

11

int top;

12

} Sym;

13

struct {

14

double data[MaxSize];

15

int top;

16

} Num;

17

double ston(char x[],int *p) {

18

int j=*p-1,i;

19

 double n=0,m=0;

20

while(x[j]>='0'&&x[j]<='9') {

21

 j--;

22

 }

23

if(x[j]!='.') {

24

for(i=j+1; i<=*p; i++) {

25

 n=10*n+(x[i]-'0');

26

 }

27

} else {

28

 for(i=j+1; i<=*p; i++) {

29

m=m+pow(0.1,i-j)*(x[i]-'0');

30

  }

31

if(x[j]=='.') {

32

*p=--j;

33

 while(x[j]>='0'&&x[j]<='9') {

34

j--;

35

  }

36

  for(i=j+1; i<=*p; i++) {

37

n=10*n+(x[i]-'0');

38

   }

39

  }

40

 }

41

 *p=j;

42

  if(x[*p]=='-') return(-(n+m));

43

return(n+m);

44

}

45

void InitStack() {

46

 Sym.top=Num.top=-1;

47

}

48

void SymPush() {

49

 if(Sym.top<MaxSize-1) {

50

  Sym.data[++Sym.top]=calc[i--];

51

 } else {

52

printf("Sym栈满 ");

53

return;

54

  }

55

}

56

void SymPop() {

57

 if(Sym.top>=0) {

58

 expr[++t]=Sym.data[Sym.top--];

59

   } else {

60

 printf("Sym栈空 ");

61

 return

62

    }

63

}

64

void NumPush() {

65

  if(Num.top<MaxSize-1) {

66

  Num.data[++Num.top]=ston(expr,&i);

67

    } else {

68

  printf("Num栈满 ");

69

  return;

70

 }

71

}

72

void NumPop() {

73

if(Num.top>=0) {

74

f(expr[i]!=' ') {

75

 switch(expr[i

76

   case '+':

77

  Num.data[Num.top-

78

1]=Num.data[Num.top]+Num.data[Num.top-1];

79

break;

80

 case '-':

81

       Num.data[Num.top-1]=Num.data[Num.top]-

82

Num.data[Num.top-1];

83

 break;

84

    case '*':

85

Num.data[Num.top-

86

1]=Num.data[Num.top]*Num.data[Num.top-1];

87

 break;

88

   case '/':

89

Num.data[Num.top-

90

1]=Num.data[Num.top]/Num.data[Num.top-1];

91

      break;

92

 case '^':

93

   Num.data[Num.top-

94

1]=pow(Num.data[Num.top],Num.data[Num.top-1]);

95

break;

96

  }

97

Num.top--;

98

   }

99

   } else {

100

 printf("Num栈空 ");

101

return;

102

  }

103

}

104

int main(void) {

105

   char ch;

106

loop1:

107

i=0,t=-1;

108

    system("cls");

109

    printf("中缀表达式:");

110

InitStack(),gets(calc);

111

while(calc[i]!='') {

112

 i++;

113

}

114

while(i>=0) {

115

  if(calc[i]>='0'&&calc[i]<='9') {

116

while((i>=0)&&((calc[i]>='0'&&calc[i]<='9')||

117

(calc[i]=='.'))) {

118

loop2:

119

  expr[++t]=calc[i--];

120

  }

121

if((i>=0)&&((i==0&&calc[i]!='(')||(calc[i]=='+'||calc[i]=='-

122

')&&!(calc[i-1]>='0'&&calc[i-1]<='9')&&calc[i-

123

1]!=')')) goto loop2;

124

expr[++t]=' ';

125

  } else if(calc[i]==')') {

126

 SymPush();

127

 } else if(calc[i]=='(') {

128

while(Sym.data[Sym.top]!=')') {

129

 SymPop();

130

    expr[++t]=' ';

131

 }

132

Sym.data[Sym.top--]='';

133

i--;

134

  } else if(calc[i]=='+'||calc[i]=='-') {

135

     while(Sym.top>=0&&Sym.data[Sym.top]!=')'&&Sym.

136

data[Sym.top]!='+'&&Sym.data[Sym.top]!='-') {

137

SymPop();

138

expr[++t]=' ';

139

   }

140

SymPush();

141

     } else if(calc[i]=='*'||calc[i]=='/') {

142

while(Sym.top>=0&&Sym.data[Sym.top]=='^') {

143

 SymPop();

144

 expr[++t]=' ';

145

 }

146

 SymPush();

147

 } else if(calc[i]=='^') {

148

SymPush();

149

 } else {

150

   i--;

151

}

152

}

153

while(Sym.top>=0) {

154

 SymPop();

155

expr[++t]=' ';

156

 }

157

expr[++t]=Sym.data[++Sym.top]='';

158

 for(i=0; i<=(t-2)/2; i++) {

159

 ch=expr[i];

160

expr[i]=expr[(t-2)-i];

161

expr[(t-2)-i]=ch;

162

 }

163

    printf("前缀表达式:%s ",expr);

164

    for(i=t-2; i>=0; i--) {

165

   if((expr[i]>='0'&&expr[i]<='9')||

166

((expr[i]=='+'||expr[i]=='-')&&(expr[i+1]>='0'&&expr[i+1]<='9'))) {

167

NumPush();

168

   } else {

169

NumPop();

170

   }

171

 }

172

 printf("运算结果为:%g ",Num.data[0]);

173

printf("Continue(y/n) ");

174

ch=getch();

175

 switch(ch) {

176

case 'y': {

公式转换

pascal代码

1

var

2

a:array[1..1000] of string;

3

s:string;

4

i,j,k,l,v:longint;

5

begin

6

readln(s);

7

j:=0; l:=length(s);

8

for i:=1 to l do

9

begin

10

if not(s[i]in['+','-','*','/']) then

11

begin

12

j:=j+1;

13

a[j]:=s[i];

14

end

15

else

16

begin

17

if (j>1)and(s[i]in['/'])and(s[i-

18

1]in['*','/']) then

19

a[j]:='('+a[j]+')';

20

j:=j-1;

21

a[j]:=a[j]+s[i]+a[j+1];

22

if (i<l)and(s[i]in['+','-']) then

23

begin

24

k:=i;

25

v:=0;

26

repeat

27

k:=k+1;

28

if s[k]in['+','-','*','/'] then v:=v-1

29

else v:=v+1;

30

until (k=l)or(v<1);

31

if (k<l)and(s[k]in['*','/']) then a[j]:='('+a[j]+')';

32

end;

33

end;

34

end;

35

end.