嵌套类递归
基础计算器 III
| #include <iostream> |
| #include <string> |
| #include <vector> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| int where; |
| |
| int calculate(string &s) { |
| where = 0; |
| return recursive(s, 0); |
| } |
| |
| |
| int recursive(string &s, int i) { |
| int cur = 0; |
| |
| vector<int> numbers; |
| |
| vector<char> ops; |
| |
| while (i < s.length()) { |
| if (s[i] >= '0' && s[i] <= '9') { |
| |
| cur = cur * 10 + s[i++] - '0'; |
| } else if (s[i] == '(') { |
| |
| cur = recursive(s, i + 1); |
| |
| i = where + 1; |
| } else if (s[i] == ')') { |
| |
| break; |
| } else { |
| |
| push(numbers, ops, cur, s[i++]); |
| cur = 0; |
| } |
| } |
| |
| push(numbers, ops, cur, '+'); |
| |
| where = i; |
| |
| return compute(numbers, ops); |
| } |
| |
| void push(vector<int> &numbers, vector<char> &ops, int cur, char op) { |
| int n = numbers.size(); |
| if (n == 0 || ops.back() == '+' || ops.back() == '-') { |
| |
| numbers.push_back(cur); |
| ops.push_back(op); |
| } else { |
| |
| int topNumber = numbers.back(); |
| char topOp = ops.back(); |
| if (topOp == '*') { |
| numbers[n - 1] = topNumber * cur; |
| } else { |
| numbers[n - 1] = topNumber / cur; |
| } |
| ops[n - 1] = op; |
| } |
| } |
| |
| |
| int compute(const vector<int> &numbers, const vector<char> &ops) { |
| int n = numbers.size(); |
| int ans = numbers[0]; |
| for (int i = 1; i < n; i++) |
| ans += ops[i - 1] == '+' ? numbers[i] : -numbers[i]; |
| return ans; |
| } |
| }; |
| |
| int main() { |
| string s = "6-4/2*(3-1)+(2+1)*(5-3*2+(4/2+2))"; |
| Solution solution; |
| cout << solution.calculate(s); |
| } |
- 递归(推荐),index++ 跳过左括号,而不是用 where + 1 去跳过
| #include <iostream> |
| #include <string> |
| #include <vector> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| int index; |
| |
| int calculate(string &s) { |
| return recursive(s); |
| } |
| |
| |
| int recursive(string &s) { |
| int cur = 0; |
| |
| vector<int> numbers; |
| |
| vector<char> ops; |
| |
| for (; index < s.length(); index++) { |
| if (s[index] >= '0' && s[index] <= '9') { |
| |
| cur = cur * 10 + s[index] - '0'; |
| } else if (s[index] == '(') { |
| |
| index++; |
| |
| cur = recursive(s); |
| } else if (s[index] == ')') { |
| |
| break; |
| } else { |
| |
| push(numbers, ops, cur, s[index]); |
| cur = 0; |
| } |
| } |
| |
| push(numbers, ops, cur, '+'); |
| |
| return compute(numbers, ops); |
| } |
| |
| void push(vector<int> &numbers, vector<char> &ops, int cur, char op) { |
| int n = numbers.size(); |
| if (n == 0 || ops.back() == '+' || ops.back() == '-') { |
| |
| numbers.push_back(cur); |
| ops.push_back(op); |
| } else { |
| |
| int topNumber = numbers.back(); |
| char topOp = ops.back(); |
| if (topOp == '*') { |
| numbers[n - 1] = topNumber * cur; |
| } else { |
| numbers[n - 1] = topNumber / cur; |
| } |
| ops[n - 1] = op; |
| } |
| } |
| |
| |
| int compute(const vector<int> &numbers, const vector<char> &ops) { |
| int n = numbers.size(); |
| int ans = numbers[0]; |
| for (int j = 1; j < n; j++) |
| ans += ops[j - 1] == '+' ? numbers[j] : -numbers[j]; |
| return ans; |
| } |
| }; |
| |
| int main() { |
| string s = "6-4/2*(3-1)+(2+1)*(5-3*2+(4/2+2))"; |
| Solution solution; |
| cout << solution.calculate(s); |
| } |
- 含有嵌套的字符串解码,时间复杂度 O(n)
- 从第一个右括号开始解析,从里向外解析每一对括号,解析成字符串后入栈,继续找下个右括号
| #include <iostream> |
| #include <string> |
| #include <vector> |
| #include <stack> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| string decodeString(string s) { |
| stack<char> stk; |
| |
| deque<char> deq; |
| |
| for (int i = 0; i < s.size(); ++i) { |
| |
| while (i < s.size() && s[i] != ']') { |
| stk.emplace(s[i]); |
| i++; |
| } |
| |
| |
| if (s[i] != ']') break; |
| |
| |
| string tempStr; |
| while (stk.top() != '[') { |
| deq.emplace_front(stk.top()); |
| stk.pop(); |
| } |
| while (!deq.empty()) { |
| tempStr += deq.front(); |
| deq.pop_front(); |
| } |
| |
| stk.pop(); |
| |
| |
| int count = 0; |
| while (!stk.empty() && stk.top() >= '0' && stk.top() <= '9') { |
| deq.emplace_front(stk.top()); |
| stk.pop(); |
| } |
| while (!deq.empty()) { |
| count *= 10; |
| count += deq.front() - '0'; |
| deq.pop_front(); |
| } |
| |
| |
| string repeated; |
| for (int j = 0; j < count; ++j) |
| repeated.append(tempStr); |
| |
| |
| for (auto &c: repeated) |
| stk.emplace(c); |
| } |
| |
| |
| string res; |
| deq.clear(); |
| while (!stk.empty()) { |
| deq.emplace_front(stk.top()); |
| stk.pop(); |
| } |
| while (!deq.empty()) { |
| res += deq.front(); |
| deq.pop_front(); |
| } |
| |
| return res; |
| } |
| }; |
- 用两个栈分别记录左括号之前的数字,以及数字前的字符串。每次遇到右括号就把括号内重复相应次数,然后与这个数字之前的字符串拼接
| class Solution { |
| public: |
| |
| |
| string decodeString(const string &s) { |
| |
| int multi = 0; |
| |
| string str; |
| stack<int> stack_multi; |
| stack<string> stack_str; |
| |
| for (char c: s) { |
| if (c == '[') { |
| |
| stack_multi.emplace(multi); |
| |
| stack_str.emplace(str); |
| |
| multi = 0; |
| str.clear(); |
| } else if (c == ']') { |
| |
| int cur_multi = stack_multi.top(); |
| stack_multi.pop(); |
| |
| string tmp; |
| for (int i = 0; i < cur_multi; i++) tmp += str; |
| |
| str = stack_str.top() + tmp; |
| stack_str.pop(); |
| } else if (c >= '0' && c <= '9') { |
| |
| multi = multi * 10 + (c - '0'); |
| } else { |
| |
| str.push_back(c); |
| } |
| } |
| return str; |
| } |
| }; |
| #include <string> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| int where; |
| |
| string recursive(string s, int i) { |
| string str; |
| int multi = 0; |
| while (i < s.length() && s[i] != ']') { |
| if (s[i] >= '0' && s[i] <= '9') { |
| |
| multi = 10 * multi + s[i++] - '0'; |
| } else if (s[i] == '[') { |
| |
| string repeatedStr = recursive(s, i + 1); |
| |
| while (multi > 0) { |
| str += repeatedStr; |
| multi--; |
| } |
| i = where + 1; |
| } else { |
| |
| str += s[i++]; |
| } |
| } |
| where = i; |
| return str; |
| } |
| |
| string decodeString(string s) { |
| where = 0; |
| return recursive(s, 0); |
| } |
| }; |
- 递归(推荐),index++ 跳过左括号,而不是用 where + 1 去跳过
| #include <string> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| int index = 0; |
| |
| string decodeString(string s) { |
| string str; |
| int multi = 0; |
| for (; index < s.size(); index++) { |
| if (s[index] >= '0' && s[index] <= '9') { |
| |
| multi = 10 * multi + s[index] - '0'; |
| } else if (s[index] == '[') { |
| |
| index++; |
| |
| string repeatedStr = decodeString(s); |
| |
| while (multi > 0) { |
| str += repeatedStr; |
| multi--; |
| } |
| } else if (s[index] == ']') { |
| |
| break; |
| } else { |
| |
| str += s[index]; |
| } |
| } |
| return str; |
| } |
| }; |
- 含有嵌套的分子式求原子数量,时间复杂度 O(n)
- 处理过程
- 遇到字母:解析出元素符号,以及该元素出现次数
- 遇到左括号
(
:递归处理这段括号的分子式,从左括号一直到右括号后面的数字
- 遇到右括号
)
:如果右括号后面是数字,则需要乘对应倍数
| #include <string> |
| #include <iostream> |
| #include <map> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| int index; |
| |
| bool isNumber(char ch) { |
| return ch >= '0' && ch <= '9'; |
| } |
| |
| bool isLowercaseLetter(char ch) { |
| return ch >= 'a' && ch <= 'z'; |
| } |
| |
| bool isUppercaseLetter(char ch) { |
| return ch >= 'A' && ch <= 'Z'; |
| } |
| |
| |
| map<string, int> recursive(string &formula) { |
| |
| map<string, int> freq; |
| |
| while (index < formula.length()) { |
| if (isUppercaseLetter(formula[index])) { |
| |
| string atom = ""; |
| atom += formula[index++]; |
| |
| while (index < formula.length() && isLowercaseLetter(formula[index])) |
| atom += formula[index++]; |
| |
| |
| int cnt = 0; |
| if (index < formula.length() && isNumber(formula[index])) { |
| while (index < formula.length() && isNumber(formula[index])) |
| cnt = cnt * 10 + formula[index++] - '0'; |
| } else { |
| |
| cnt = 1; |
| } |
| freq[atom] += cnt; |
| } else if (formula[index] == '(') { |
| index++; |
| |
| map<string, int> tempCount = recursive(formula); |
| |
| for (const auto &item: tempCount) |
| freq[item.first] += item.second; |
| |
| } else if (formula[index] == ')') { |
| index++; |
| |
| if (index < formula.length() && isNumber(formula[index])) { |
| int cnt = 0; |
| while (index < formula.length() && isNumber(formula[index])) |
| cnt = cnt * 10 + formula[index++] - '0'; |
| for (auto &item: freq) |
| freq[item.first] = item.second * cnt; |
| } |
| |
| return freq; |
| } |
| } |
| return freq; |
| } |
| |
| string countOfAtoms(string formula) { |
| index = 0; |
| map<string, int> count = recursive(formula); |
| string res; |
| |
| for (const auto &item: count) { |
| res.append(item.first); |
| if (item.second != 1) |
| res.append(to_string(item.second)); |
| } |
| return res; |
| } |
| }; |
本文作者:sprinining
本文链接:https://www.cnblogs.com/sprinining/p/18449114
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2021-10-06 RecyclerView刷新方式