天天看點

nyoj 1272(表達式求值)

表達式求值

時間限制: 1000 ms  |  記憶體限制: 65535 KB 難度: 3

描述
假設表達式定義為: 1. 一個十進制的正整數 X 是一個表達式。 2. 如果 X 和 Y 是 表達式,則 X+Y, X*Y 也是表達式; *優先級高于+. 3. 如果 X 和 Y 是 表達式,則 函數 Smax(X,Y)也是表達式,其值為:先分别求出 X ,Y 值的各位數字之和,再從中選最大數。 4.如果 X 是 表達式,則 (X)也是表達式。 例如: 表達式 12*(2+3)+Smax(333,220+280) 的值為 69。 請你程式設計,對給定的表達式,輸出其值。  
輸入
【标準輸入】 第一行: T 表示要計算的表達式個數 (1≤ T ≤ 10) 接下來有 T 行, 每行是一個字元串,表示待求的表達式,長度<=1000
輸出
【标準輸出】 對于每個表達式,輸出一行,表示對應表達式的值。
樣例輸入
3
12+2*3
12*(2+3)
12*(2+3)+Smax(333,220+280)      
樣例輸出
18
60
69      

來源

河南省第九屆省賽

這道題表達式求值題類似于nyoj35和nyoj305.這道題多了個Smax運算,其實思路都是一樣的,就是把Smax的優先級定為最高的就行,同樣有兩種解題思路,一是先把中綴表達式轉化為字尾表達式,再進行運算,第二種是在進行周遊表達式的時候就進行計算:

代碼1:

 C++ Code 

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

#include <iostream>

#include <cstdio>

#include <cstring>

#include <stack>

using  namespace std;

const  int maxn= 1000+ 5;

string s1,s2;

stack< char> s;

stack< double> c;

void init()

{

     ///對兩個棧進行初始化

     while(!s.empty())

        s.pop();

     while(!c.empty())

        c.pop();

}

int pro( char ch)

{

     ///規定運算符的優先級

     switch(ch)

    {

     case  '+':

     case  '-':

         return  1;

     case  '*':

     case  '/':

         return  2;

     case  'S':

         return  3;

     default :

         return  0;

    }

}

void deal()

{

    init();

     int i= 0,len=s1.length();

    s.push( '#');

     while(i<len)

    {

         if(s1[i]== '(')

            s.push(s1[i++]);

         else  if(s1[i]== 'S')

        {

            s.push(s1[i]);

            i=i+ 4;

        }

         else  if(s1[i]== ')')

        {

             while(s.top()!= '(')

            {

                s2+=s.top();

                s2+= ' ';

                s.pop();

            }

            s.pop();

            i++;

        }

         else  if(s1[i]== '+'||s1[i]== '-'||s1[i]== '*'||s1[i]== '/'||s1[i]== 'S')

        {

             while(pro(s.top())>=pro(s1[i]))

            {

                s2+=s.top();

                s2+= ' ';

                s.pop();

            }

            s.push(s1[i]);

            i++;

        }

         else  if(s1[i]<= '9'&&s1[i]>= '0'||s1[i]== '.')

        {

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

                s2+=s1[i++];

            s2+= ' ';

        }

         else  if(s1[i]== ','||s1[i]== 'x')

            i++;

    }

     while(s.top()!= '#')

    {

        s2+=s.top();

        s.pop();

        s2+= ' ';

    }

     //cout<<s2<<endl;

}

double countt()

{

     int len=s2.length(),i= 0;

     double y,x;

     while(i<len)

    {

         if(s2[i]== ' ')

            i++;

         else

        {

             switch(s2[i])

            {

             case  '+':

                x=c.top();

                c.pop();

                x+=c.top();

                c.pop();

                i++;

                 break;

             case  '*':

                x=c.top();

                c.pop();

                x*=c.top();

                c.pop();

                i++;

                 break;

             case  'S':

            {

                 int a=c.top();

                c.pop();

                 int b=c.top();

                c.pop();

                 int c,da =  0,db =  0;

                 while(b!= 0)

                {

                    db += b% 10;

                    b /=  10;

                }

                 while(a!= 0)

                {

                    da += a% 10;

                    a /=  10;

                }

                x = max(da,db);

                i++;

                 break;

            }

             default :

            {

                x= 0. 0;

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

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

            }

            }

            c.push(x);

        }

    }

     return c.top();

}

int main()

{

     int t;

    cin>>t;

     while(t--)

    {

        cin>>s1;

        s2= "";

        deal();

        printf( "%.0lf\n",countt());

    }

     return  0;

}

代碼2:

 C++ Code 

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

#include <stdio.h>  

#include <string.h>  

#include <algorithm>  

#include <stack>  

using  namespace std;  

stack< char> s1;  

stack< int> s2;  

char s[ 1010];  

int main()  

{  

     int T;  

    scanf( "%d",&T);  

     while(T--)  

    {  

         int i,j;  

        getchar();  

        scanf( "%s",&s[ 1]);  

         int len = strlen(&s[ 1]);  

        s[ 0] =  '(';  

        s[len+ 1] =  ')';  

        len++;  

         for(i= 0;i<=len;i++)  

        {  

             if(s[i]== '(')  

            {  

                s1.push(s[i]);  

            }  

             else  if(s[i]== 'S')  

            {  

                s1.push( '(');  

                s1.push( 'S');  

                i +=  4;  

            }  

             else  if(s[i]>= '0' && s[i]<= '9')  

            {  

                 int v =  0;  

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

                {  

                    v = v* 10+(s[i++]- '0');  

                }  

                i--;  

                s2.push(v);  

            }  

             else  if(s[i]== '+' || s[i]== '-')  

            {  

                 while(s1.top()!= '(' && s1.top()!= 'S')  

                {  

                     int a = s2.top(); s2.pop();  

                     int b = s2.top(); s2.pop();  

                     int c;  

                     switch(s1.top())  

                    {  

                         case  '+': c = b + a;  break;  

                         case  '-': c = b - a;  break;  

                         case  '*': c = b * a;  break;  

                         case  '/': c = b / a;  break;  

                    }  

                    s2.push(c);  

                    s1.pop();  

                }  

                s1.push(s[i]);  

            }  

             else  if(s[i]== '*' || s[i]== '/')  

            {  

                 if(s1.top()== '*' )  

                {  

                     int a = s2.top(); s2.pop();  

                     int b = s2.top(); s2.pop();  

                    s2.push(b*a);  

                    s1.pop();  

                }  

                 else  if(s1.top()== '/')  

                {  

                     int a = s2.top();s2.pop();  

                     int b = s2.top();s2.pop();  

                    s2.push(b/a);  

                    s1.pop();  

                }  

                s1.push(s[i]);  

            }  

             else  if(s[i]== ')')  

            {  

                 while(s1.top()!= '(' &&  s1.top()!= 'S')  

                {  

                     int a = s2.top();s2.pop();  

                     int b = s2.top();s2.pop();  

                     int c,da =  0 ,db =  0;  

                     switch(s1.top())  

                    {  

                         case  '+': c = b + a;  break;  

                         case  '-': c = b - a;  break;  

                         case  '*': c = b * a;  break;  

                         case  '/': c = b / a;  break;  

                    }  

                    s2.push(c);  

                    s1.pop();  

                }  

                 if(s1.top()== 'S')     

                {  

                     int a=s2.top();s2.pop();  

                     int b=s2.top();s2.pop();  

                     int c,da =  0 ,db =  0;  

                     while(b!= 0)  

                    {  

                        db += b% 10;  

                        b /=  10;  

                    }  

                     while(a!= 0)  

                    {  

                        da += a% 10;  

                        a /=  10;  

                    }  

                    c = max(da,db);  

                    s2.push(c);  

                    s1.pop();  

                }  

                s1.pop();             

            }  

        }  

        printf( "%d\n",s2.top());  

        s2.pop();  

    }  

     return  0;  

}