计算器、中文转数字
計算器
1.字符串轉(zhuǎn)整數(shù)
string s = "458";int n = 0; for (int i = 0; i < s.size(); i++) {char c = s[i];n = 10 * n + (c - '0'); } // n 現(xiàn)在就等于 4582.處理加減法
我們拿字符串算式1-12+3為例,來說一個很簡單的思路:
1、先給第一個數(shù)字加一個默認符號+,變成+1-12+3。
2、把一個運算符和數(shù)字組合成一對兒,也就是三對兒+1,-12,+3,把它們轉(zhuǎn)化成數(shù)字,然后放到一個棧中。
3、將棧中所有的數(shù)字求和,就是原算式的結(jié)果。
int calculate(string s) {stack<int> stk;// 記錄算式中的數(shù)字int num = 0;// 記錄 num 前的符號,初始化為 +char sign = '+';for (int i = 0; i < s.size(); i++) {char c = s[i];// 如果是數(shù)字,連續(xù)讀取到 numif (isdigit(c)) num = 10 * num + (c - '0');// 如果不是數(shù)字,就是遇到了下一個符號,// 之前的數(shù)字和符號就要存進棧中if (!isdigit(c) || i == s.size() - 1) {switch (sign) {case '+':stk.push(num); break;case '-':stk.push(-num); break;}// 更新符號為當前符號,數(shù)字清零sign = c;num = 0;}}// 將棧中所有結(jié)果求和就是答案int res = 0;while (!stk.empty()) {res += stk.top();stk.pop();}return res; }i就是從左到右掃描,sign和num跟在它身后。當s[i]遇到一個運算符時,情況是這樣的
所以說,此時要根據(jù)sign的 case 不同選擇nums的正負號,存入棧中,然后更新sign并清零nums記錄下一對兒符合和數(shù)字的組合。
另外注意,不只是遇到新的符號會觸發(fā)入棧,當i走到了算式的盡頭(i == s.size() - 1),也應(yīng)該將前面的數(shù)字入棧,方便后續(xù)計算最終結(jié)果。
3. 處理乘除法
for (int i = 0; i < s.size(); i++) {char c = s[i];if (isdigit(c)) num = 10 * num + (c - '0');if (!isdigit(c) || i == s.size() - 1) {switch (sign) {int pre;case '+':stk.push(num); break;case '-':stk.push(-num); break;// 只要拿出前一個數(shù)字做對應(yīng)運算即可case '*':pre = stk.top();stk.pop();stk.push(pre * num);break;case '/':pre = stk.top();stk.pop();stk.push(pre / num);break;}// 更新符號為當前符號,數(shù)字清零sign = c;num = 0;} }乘除法優(yōu)先于加減法體現(xiàn)在,乘除法可以和棧頂?shù)臄?shù)結(jié)合,而加減法只能把自己放入棧。
4.處理括號
那么,為什么說處理括號沒有看起來那么難呢,因為括號具有遞歸性質(zhì)。我們拿字符串3*(4-5/2)-6舉例:
calculate(3*(4-5/2)-6)
= 3 * calculate(4-5/2) - 6
= 3 * 2 - 6
= 0
可以腦補一下,無論多少層括號嵌套,通過 calculate 函數(shù)遞歸調(diào)用自己,都可以將括號中的算式化簡成一個數(shù)字。換句話說,括號包含的算式,我們直接視為一個數(shù)字就行了。
現(xiàn)在的問題是,遞歸的開始條件和結(jié)束條件是什么?遇到(開始遞歸,遇到)結(jié)束遞歸:python版本
def calculate(s: str) -> int:def helper(s: List) -> int:stack = []sign = '+'num = 0while len(s) > 0:c = s.pop(0)if c.isdigit():num = 10 * num + int(c)# 遇到左括號開始遞歸計算 numif c == '(':num = helper(s)if (not c.isdigit() and c != ' ') or len(s) == 0:if sign == '+': ...elif sign == '-': ... elif sign == '*': ...elif sign == '/': ...num = 0sign = c# 遇到右括號返回遞歸結(jié)果if c == ')': breakreturn sum(stack)return helper(list(s))Java版本:224. 基本計算器?
public int calculate(String s) {// Write your code hereDeque<Character> q = new LinkedList<>();for (char c : s.toCharArray()) {q.offer(c);}return dfs_cal(q); } // 得到括號內(nèi)的結(jié)果 public int dfs_cal(Deque<Character> q) {Stack<Integer> stack = new Stack<>();char op = '+';int num = 0;while (!q.isEmpty()) {char c = q.pollFirst();if (c == '(') {num = dfs_cal(q);}if (Character.isDigit(c)) {num = num * 10 + c - '0';}// 讀取到最后一位時 要處理最后的邏輯if (q.isEmpty() || (!Character.isDigit(c) && c != ' ')) {if (op == '+') {stack.push(num);} else if (op == '-') {stack.push(-num);} else if (op == '*') {stack.push(stack.pop() * num);} else if (op == '/') {stack.push(stack.pop() / num);}op = c;num = 0;}// 右括號判斷只能在最后 前面要處理計算邏輯if (c == ')') {break;}}int res = 0;for (int t : stack) {res += t;}return res; }中文轉(zhuǎn)阿拉伯
//中文字轉(zhuǎn)阿拉伯數(shù)字public long zn_int(String num){if (num == null || num.length() == 0) return 0L;HashMap<Character, Long> numMap = new HashMap<>();numMap.put('零', 0L);numMap.put('一', 1L);numMap.put('二', 2L);numMap.put('三', 3L);numMap.put('四', 4L);numMap.put('五', 5L);numMap.put('六', 6L);numMap.put('七', 7L);numMap.put('八', 8L);numMap.put('九', 9L);numMap.put('十', 10L);numMap.put('廿', 20L);numMap.put('卅', 30L);numMap.put('百', 100L);numMap.put('千', 1000L);numMap.put('萬', 10_000L);numMap.put('億', 100_000_000L);long tmpres = 0;//year 2 longfor (char c : num.toCharArray()){long cur = numMap.get(c);if (cur >= 10) {tmpres = -1;break;}tmpres = tmpres*10 + cur;}if (tmpres > 0) return tmpres;LinkedList <Long> stack = new LinkedList<>();for (char c : num.toCharArray()){long cur = numMap.get(c);if (stack.isEmpty() || stack.peek() > cur){stack.push(cur);}else {long sum = 0;while (!stack.isEmpty() && stack.peek() < cur) {sum += stack.pop();}sum = (sum == 0 ? 1 : sum);stack.push(sum * cur);}}long res = 0;for (long t : stack){res += t;}return res;}總結(jié)
- 上一篇: Python代码编辑器jupyter的安
- 下一篇: oracle 052 题库变了,orac