第十六次 ccf 201903-2 二十四點


 題意:

        計算數學表達式的值,

       數學表達式的定義: 4個[0-9]表示數字的字符 ,3個[+-x/]表示運算的字符

       可以用正則為: ([0-9][+-x/]){3}[0-9]

       例如: 5+2/1x3

                 2-1+7x3

                 3x3/3x3

 找到圖片了,不啰嗦了...

 

  這道題只有7個字符,數字只有一位不算太難

  先算乘除,后算加減,考試的時候就是這樣做的,用stack完美解決

  但如果加大難度....

  1)  數字允許有多位比如  1314-521*233

  2) 再比如如果有括號呢   -1-(1-(-9))

  讓我們按照函數化的思想逐漸完善我們的代碼

 

  (1) 7個字符版本

 

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <stack>
 4 using namespace std;
 5 int get_ans (string str) {
 6     stack <int> s;
 7     int flag=1;
 8     for (int i=0;i<str.size();i++) {
 9         if (str[i]>='0'&&str[i]<='9') s.push( flag*(str[i]-'0'));
10         else if (str[i]=='-' || str[i]=='+')  {
11             if (str[i]=='-') flag=-1;
12             else             flag=1;
13         }
14         else {
15             int x1=s.top(); s.pop();
16             i++; // importment !!
17             int x2=str[i]-'0';
18             if (str[i-1]=='/')  s.push(x1/x2);
19             else               s.push(x1*x2);
20         }
21     }
22     int sum=0;
23     while (!s.empty()) {
24         sum+=s.top();
25         s.pop();
26     }
27     return sum;
28 }
29 int main ()
30 {
31     int T; cin>>T;
32     while (T--) {
33         string str; cin>>str;
34         cout<<get_ans(str)<<endl;
35     }
36     return 0;
37 }

 

2   允許有連續的輸入數字:     233*521

  我們加入一個輸入接口get_num: 如果下一個字符是數字,就一直讀下去

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <stack>
 4 using namespace std;
 5 
 6 int get_num(string str,int &k) { 
 7     // 從k開始一直讀所有的數字字符
 8     int ans=0;
 9     for (;k<str.size();k++) {
10         if (str[k]>='0' && str[k]<='9')
11             ans=ans*10+str[k]-'0';
12         else break;
13     }
14     k--; // i 此時指向最后一個數字的位置 
15     return ans;
16 }
17 
18 int get_ans (string str) {
19     stack <int> s;
20     int flag=1;
21     for (int i=0;i<str.size();i++) {
22         if (str[i]>='0'&&str[i]<='9')  {
23             int num=get_num(str,i);
24             s.push(flag*num);
25         }
26         else if (str[i]=='-' || str[i]=='+')  {
27             if (str[i]=='-') flag=-1;
28             else             flag=1;
29         }
30         else {
31             char ch=str[i];
32             int x1=s.top(); s.pop();
33             i++;
34             int x2=get_num(str,i);
35             if (ch=='/')  s.push(x1/x2);
36             else          s.push(x1*x2);
37         }
38     }
39     int sum=0;
40     while (!s.empty()) {
41         sum+=s.top();
42         s.pop();
43     }
44     return sum;
45 }
46 
47 int main ()
48 {
49     int T; cin>>T;
50     while (T--) {
51         string str; cin>>str;
52         cout<<get_ans(str)<<endl;
53     }
54     return 0;
55 }

 

3  最難的部分,遇到括號怎么辦---

   我們也只需要加一個接口

   其核心就是把一對括號里面的字符,放入我們之前的接口算出結果,從而達到去除括號的效果

  例子:  1*(3-(5-4)) ->1*(3-1)->1*2>2

   總之就是把一個問題切分成一個一個小問題

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <stack>
 4 using namespace std;
 5 string to_str (int x) {
 6     if (x==0) return "0";
 7     string ans;
 8     bool flag=0;
 9     if (x<0) {
10         flag=1;
11         x=-x;
12     }
13     while (x) {
14         ans+=x%10+'0';
15         x/=10;
16     }
17     if (flag) ans+='-';
18     return ans;
19 }
20 
21 int get_num(string str,int &k) {
22     int ans=0;
23     for (;k<str.size();k++) {
24         if (str[k]>='0' && str[k]<='9')
25             ans=ans*10+str[k]-'0';
26         else break;
27     }
28     k--; // i 此時指向最后一個數字的位置 
29     return ans;
30 }
31 
32 int get_no_ans (string str) {
33     stack <int> s;
34     int flag=1;
35     for (int i=0;i<str.size();i++) {
36         if (str[i]>='0'&&str[i]<='9')  {
37             int num=get_num(str,i);
38             s.push(flag*num);
39         }
40         else if (str[i]=='-' || str[i]=='+')  {
41             if (str[i]=='-')  {
42                 if (i-1&&str[i-1]=='-') flag=-flag;
43                 else                    flag=-1;
44             }
45             else             flag=1;
46         }
47         else {
48             char ch=str[i];
49             int x1=s.top(); s.pop();
50             i++;
51             int x2=get_num(str,i);
52             if (ch=='/')  s.push(x1/x2);
53             else          s.push(x1*x2);
54         }
55     }
56     int sum=0;
57     while (!s.empty()) {
58         sum+=s.top();
59         s.pop();
60     }
61     return sum;
62 }
63 
64 int get_ans (string str) {
65     str="("+str+")";
66     stack <char> s;
67     int ans;
68     for (int i=0;i<str.size();i++) {
69         if (str[i]==')') {
70             string tmp;
71             while (s.top()!='(') {
72                 tmp+=s.top();
73                 s.pop();
74             }
75             s.pop();
76             reverse(tmp.begin(), tmp.end());
77             int num=get_no_ans(tmp);
78             //cout<<tmp<<"@@@"<<num<<endl;
79             tmp=to_str(num);
80             for (int j=tmp.size()-1;j>=0;j--) s.push(tmp[j]);
81             if (i==str.size()-1) ans=num;
82         }
83         else s.push(str[i]);
84     }
85     return ans;
86 }
87 
88 int main ()
89 {
90     int T; cin>>T;
91     while (T--) {
92         string str; cin>>str;
93         cout<<get_ans(str)<<endl;
94     }
95     return 0;
96 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM