计算器、中文转数字

计算器

1.字符串转整数

string s = "458";int n = 0;
for (int i = 0; i < s.size(); i++) {char c = s[i];n = 10 * n + (c - '0');
}
// n 现在就等于 458

2.处理加减法

我们拿字符串算式1-12+3为例,来说一个很简单的思路:

1、先给第一个数字加一个默认符号+,变成+1-12+3

2、把一个运算符和数字组合成一对儿,也就是三对儿+1-12+3,把它们转化成数字,然后放到一个栈中。

3、将栈中所有的数字求和,就是原算式的结果。

int calculate(string s) {stack<int> stk;// 记录算式中的数字int num = 0;// 记录 num 前的符号,初始化为 +char sign = '+';for (int i = 0; i < s.size(); i++) {char c = s[i];// 如果是数字,连续读取到 numif (isdigit(c)) num = 10 * num + (c - '0');// 如果不是数字,就是遇到了下一个符号,// 之前的数字和符号就要存进栈中if (!isdigit(c) || i == s.size() - 1) {switch (sign) {case '+':stk.push(num); break;case '-':stk.push(-num); break;}// 更新符号为当前符号,数字清零sign = c;num = 0;}}// 将栈中所有结果求和就是答案int res = 0;while (!stk.empty()) {res += stk.top();stk.pop();}return res;
}

i就是从左到右扫描,signnum跟在它身后。s[i]遇到一个运算符时,情况是这样的

图片

所以说,此时要根据sign的 case 不同选择nums的正负号,存入栈中,然后更新sign并清零nums记录下一对儿符合和数字的组合。

另外注意,不只是遇到新的符号会触发入栈,当i走到了算式的尽头(i == s.size() - 1),也应该将前面的数字入栈,方便后续计算最终结果。

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;// 只要拿出前一个数字做对应运算即可case '*':pre = stk.top();stk.pop();stk.push(pre * num);break;case '/':pre = stk.top();stk.pop();stk.push(pre / num);break;}// 更新符号为当前符号,数字清零sign = c;num = 0;}
}

乘除法优先于加减法体现在,乘除法可以和栈顶的数结合,而加减法只能把自己放入栈

图片

4.处理括号

那么,为什么说处理括号没有看起来那么难呢,因为括号具有递归性质。我们拿字符串3*(4-5/2)-6举例:

calculate(3*(4-5/2)-6)
= 3 * calculate(4-5/2) - 6
= 3 * 2 - 6
= 0

可以脑补一下,无论多少层括号嵌套,通过 calculate 函数递归调用自己,都可以将括号中的算式化简成一个数字。换句话说,括号包含的算式,我们直接视为一个数字就行了

现在的问题是,递归的开始条件和结束条件是什么?遇到(开始递归,遇到)结束递归: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# 遇到右括号返回递归结果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);
}
// 得到括号内的结果
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;
}

中文转阿拉伯

//中文字转阿拉伯数字
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);// year 2 long 年份判断 一九四五 这种long tmpres = 0; for (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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/418299.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端学习(2009)vue之电商管理系统电商系统之渲染商品属性的结构

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

浏览器上请求URL的全部过程

分为六步 1. 域名解析   浏览器首先要做去获得想访问网页的IP地址&#xff0c;浏览器会发送一个UDP的包给DNS域名解析服务器。DNS就会返回给我们百度的IP地址&#xff0c;通常来说浏览器会把访问过的网站的IP保存下来&#xff0c;这样下次访问的时候就会快很多&#xff0c;能…

前端学习(2013)vue之电商管理系统电商系统之监听on-success事件

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

常见算法复习整理1

数据结构笔记 1.迭代与递归 递归过程中的递归因子本身可以被忽略&#xff08;被计入它自己的过程中了&#xff09; 递归跟踪、递推方程。递归基 减而治之&#xff1a;Decrease and Conquer 线性递归的模式 T(n) T(n-1) O(1) 分而治之&#xff1a;Divide and Conquer 一般…

前端学习(2014)vue之电商管理系统电商系统之监听on-remove事件

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

HIT计网笔记

一、实践课笔记 1. 路由器连接的是两个不同的网络&#xff0c;交换机连接的是同一个网络。路由器负责在不同网段转移数据&#xff0c;交换机看mac地址&#xff0c;路由器看ip地址。 2. 子网掩码可以分离出IP地址中的网络地址和主机地址&#xff0c;同一个网络的网络地址相同&…

前端学习(2015)vue之电商管理系统电商系统之实现图片的预览效果

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

几种排序与最大K问题

图片链接 0. 链表归并和快排 链表排序常用归并&#xff0c;但是快排面试常出&#xff1b; 一定要理解归并的本质&#xff1a; 两步走&#xff1a; 1. 先切分成(有序)两部分&#xff0c;此处各部分都是有序的 2. 两部分有序合并 切分成两部分的最小粒度是一个元素&#…

前端学习(2016)vue之电商管理系统电商系统vue-quill-editor

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

经典算法题:字典树、并查集、单调栈、二分、带标记函数dp、树、全排列、字符串问题等常用算法

0. Tips 1. 位运算 如何枚举一个二进制状态数字k的子集, 方法就是针对中的二进制为1的位开始进行减法&#xff0c;判断数字k的二进制子集, 像枚举(2^k-1) ~ 0一样枚举其子集&#xff1b; int sub k;do {sub (sub - 1) & k;} while(sub ! k); 比如k 10101的二进制子集…

web窗体的内置对象

内置对象&#xff1a;1、Response - 响应请求对象 Response.Redirect("Default2.aspx"); //重定向 Response.Write("<script>window.open(Default2.aspx);</script>"); ---可以书写任何东西&#xff0c;直接输出出去2、Request - 接收请求对象…

前端学习(2017)vue之电商管理系统电商系统实现表单的预先认证

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

Docker有什么好处?

Docker背后的想法是创建软件程序可移植的轻量容器&#xff0c;让其可以在任何安装了Docker的机器上运行&#xff0c;而不用关心底层操作系统&#xff0c;类似船舶使用的集装箱&#xff0c;野心勃勃的他们成功了。 Docker可以解决虚拟机能够解决的问题&#xff0c;同时也能够解决…

前端学习(2018)vue之电商管理系统电商系统把good_cat转换为字符串

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

前端学习(2019)vue之电商管理系统电商系统处理attr参数

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

Java JNI初探

---说明&#xff0c;之前直接百度出来的例子&#xff0c;照猫画虎。没想到的是这例子居然直接来自百度百科&#xff0c;写着写着就囧了。。 ---anyway&#xff0c;写完了就当是给自己看吧。 同事求助&#xff0c;就看了一下&#xff0c;照猫画虎一番&#xff0c;略有所得。 JNI…

前端学习(2020)vue之电商管理系统电商系统之完成商品添加操作

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

webScoket的浅短的认识

在一般的发送数据请求的时候都是用的http协议&#xff0c;但是对于类似即时聊天&#xff0c;需要客户端与服务器不间断的交互的时候对于http协议来说就不太适用了。因为http协议无法主动把数据发到客户端&#xff0c;而且客户端发送请求之后就会断开连接&#xff0c;无法达到我…