展开括号中字符串
就是有数字有字母,括号,要求按括号展开字符串,并且匹配相应模式
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 string parse (const string& s) { stack<int > numStk; stack<string> strStk; string res; int num = 0 ; for (char c : s) { if (isdigit (c)) { num = num * 10 + (c - '0' ); } else if (c == '(' ) { numStk.push (num); num = 0 ; strStk.push (res); res = "" ; } else if (c == ')' ) { string temp = res; for (int i = 0 ; i < numStk.top () - 1 ; ++i) { res += temp; } res = strStk.top () + res; strStk.pop (); numStk.pop (); } else { res += c; } } return res; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 def parse (s ): num_stack = [] str_stack = [] res = "" num = 0 for c in s: if c.isdigit(): num = num * 10 + int (c) elif c == '(' : num_stack.append(num) num = 0 str_stack.append(res) res = "" elif c == ')' : temp = res for _ in range (num_stack.pop() - 1 ): res += temp res = str_stack.pop() + res else : res += c return res
求后缀表达式
洛谷P14449
就是根据后缀表达式来求出最后的结果,无需转换,计算机最喜欢后缀表达式了
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 #include <bits/stdc++.h> using namespace std;int todig (string s) { int t = 0 ; for (auto i : s) { t = (i - '0' ) + t* 10 ; } return t; }int main () { string s;cin >> s; map<char ,int >mp; mp['.' ] = 1 ; mp['+' ] = 2 ; mp['-' ] = 3 ; mp['*' ] = 4 ; mp['/' ] = 5 ; stack <int > st; string num = "" ; for (auto i : s) { if (mp[i]==1 ) { int t = todig (num); num = "" ; st.push (t); }else if (mp[i]>1 ) { int a = st.top (); st.pop (); int b = st.top (); st.pop (); if (i=='+' ) st.push (a+b); if (i=='-' ) st.push (b-a); if (i=='*' ) st.push (b*a); if (i=='/' ) st.push (b/a); }else { num+=i; } } cout << st.top (); return 0 ; }
中缀表达式
洛谷P1175
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 #include <bits/stdc++.h> using namespace std;typedef long long LL; map<char ,int >mp; string s;string fun1 () { vector <char > vi; string vs; stack <char > st; for (auto i : s) { if (mp[i]>=2 && mp[i]<=4 ) { if (st.empty ()) { st.push (i); }else { while (mp[st.top ()] >= mp[i]) { vs+=st.top (); st.pop (); if (st.empty ()) { break ; } } st.push (i); } }else if (mp[i]==1 ) { st.push (i); }else if (mp[i]==5 ) { while (mp[st.top ()]!=1 ) { if (mp[i]!=1 ) vs+=st.top (); st.pop (); } st.pop (); } else { vs+=i; } } while (!st.empty ()) { if (st.top ()!='(' ) vs+=st.top (); st.pop (); } return vs; }void ct (string vs) { for (auto i : vs) cout << i << " " ; cout <<"\n" ; vector<int >vi; for (int i = 0 ;i<vs.size ();i++) { if (vs[i]>='0' && vs[i]<='9' ) { vi.push_back (vs[i] -'0' ); }else { int a = vi.back (); vi.pop_back (); int b = vi.back (); vi.pop_back (); char op = vs[i]; if (op=='+' ) vi.push_back (a+b); else if (op=='-' ) vi.push_back (b-a); else if (op=='*' ) vi.push_back (b*a); else if (op=='/' ) vi.push_back (b/a); else if (op=='^' ) vi.push_back (pow (b,a)); for (auto n : vi) cout << n <<" " ; for (int j = i +1 ;j<vs.size ();j++) cout << vs[j]<<" " ; cout << "\n" ; } } }int main () { cin >> s; mp['(' ] = 1 ; mp['^' ] = 4 ; mp['+' ] = 2 ; mp['-' ] = 2 ; mp['*' ] = 3 ; mp['/' ] = 3 ; mp[')' ] = 5 ; ct (fun1 ()); return 0 ; }
题目要求算出后缀表达式,并且一步步的求解最后的结果,具体里面的分析就是先判断优先级,需要处理括号的两个特殊情况,还有里面因为变量名的问题,导致出来了好几个问题,特别是vs和s的处理
用栈来模拟递归
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 #include <bits/stdc++.h> using namespace std;int dfs (int x) { if (x<10 ) return x*10 + x; int a = dfs (x/10 ); int b = dfs (x%10 ); return a*100 +b; }int stdfs (int x) { stack <int >st; while (x!=0 ) { st.push (x); x/=10 ; } int sum = 0 ; while (!st.empty ()){ int top = st.top (); st.pop (); if (top>10 ){ sum = sum*100 + (top%10 )*11 ; }else { sum = top*11 ; } } return sum; }int main () { int n;cin >> n; cout << dfs (n)<<"\n" ; cout << stdfs (n); return 0 ; }
处理这类问题的基本方法就是,先将需要求的,也就是每次递归调用的参数放入栈中,然后分别取出栈内的元素,再做具体的操作,乘法或者相加之类的操作,就是按照先后顺序