返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++实现添加括号的不同方式
  • 691
分享到

C++实现添加括号的不同方式

2023-06-20 16:06:47 691人浏览 独家记忆
摘要

本篇内容介绍了“c++实现添加括号的不同方式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!添加括号的不同方式Given a string o

本篇内容介绍了“c++实现添加括号的不同方式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

添加括号的不同方式

Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +, - and *.

Example 1:

Input:

"2-1-1"

Output:

[0, 2]

Explanation:
((2-1)-1) = 0
(2-(1-1)) = 2

Example 2:

Input: "2*3-4*5"
Output: [-34, -14, -10, -10, 10]
Explanation:
(2*(3-(4*5))) = -34
((2*3)-(4*5)) = -14
((2*(3-4))*5) = -10
(2*((3-4)*5)) = -10
(((2*3)-4)*5) = 10

这道题让给了一个可能含有加减乘的表达式,让我们在任意位置添加括号,求出所有可能表达式的不同值。这道题乍一看感觉还蛮难的,给人的感觉是既要在不同的位置上加括号,又要计算表达式的值,结果一看还是道 Medium 的题,直接尼克杨问号脸?!遇到了难题不要害怕,从最简单的例子开始分析,慢慢的找规律,十有八九就会在分析的过程中灵光一现,找到了破题的方法。这道题貌似默认输入都必须是合法的,虽然题目中没有明确的指出这一点,所以我们也就不必进行 valid 验证了。先从最简单的输入开始,若 input 是空串,那就返回一个空数组。若 input 是一个数字的话,那么括号加与不加其实都没啥区别,因为不存在计算,但是需要将字符串转为整型数,因为返回的是一个整型数组。当然,input 是一个单独的运算符这种情况是不存在的,因为前面说了这道题默认输入的合法的。下面来看若 input 是数字和运算符的时候,比如 "1+1" 这种情况,那么加不加括号也没有任何影响,因为只有一个计算,结果一定是2。再复杂一点的话,比如题目中的例子1,input 是 "2-1-1" 时,就有两种情况了,(2-1)-1 和 2-(1-1),由于括号的不同,得到的结果也不同,但如果我们把括号里的东西当作一个黑箱的话,那么其就变为 ()-1  和 2-(),其最终的结果跟括号内可能得到的值是息息相关的,那么再 general 一点,实际上就可以变成 () ? () 这种形式,两个括号内分别是各自的表达式,最终会分别计算得到两个整型数组,中间的问号表示运算符,可以是加,减,或乘。那么问题就变成了从两个数组中任意选两个数字进行运算,瞬间变成我们会做的题目了有木有?而这种左右两个括号代表的黑盒子就交给递归去计算,像这种分成左右两坨的 pattern 就是大名鼎鼎的分治法 Divide and Conquer 了,是必须要掌握的一个神器。类似的题目还有之前的那道 Unique Binary Search Trees II 用的方法一样,用递归来解,划分左右子树,递归构造。

好,继续来说这道题,我们不用新建递归函数,就用其本身来递归就行,先建立一个结果 res 数组,然后遍历 input 中的字符,根据上面的分析,我们希望在每个运算符的地方,将 input 分成左右两部分,从而扔到递归中去计算,从而可以得到两个整型数组 left 和 right,分别表示作用两部分各自添加不同的括号所能得到的所有不同的值,此时我们只要分别从两个数组中取数字进行当前的运算符计算,然后把结果存到 res 中即可。当然,若最终结果 res 中还是空的,那么只有一种情况,input 本身就是一个数字,直接转为整型存入结果 res 中即可,参见代码如下:

解法一:

class Solution {public:    vector<int> diffWaysToCompute(string input) {        vector<int> res;        for (int i = 0; i < input.size(); ++i) {            if (input[i] == '+' || input[i] == '-' || input[i] == '*') {                vector<int> left = diffWaysToCompute(input.substr(0, i));                vector<int> right = diffWaysToCompute(input.substr(i + 1));                for (int j = 0; j < left.size(); ++j) {                    for (int k = 0; k < right.size(); ++k) {                        if (input[i] == '+') res.push_back(left[j] + right[k]);                        else if (input[i] == '-') res.push_back(left[j] - right[k]);                        else res.push_back(left[j] * right[k]);                    }                }            }        }        if (res.empty()) res.push_back(stoi(input));        return res;    }};

我们也可以使用 HashMap 来保存已经计算过的情况,这样可以减少重复计算,从而提升运算速度,以空间换时间,岂不美哉,参见代码如下:

解法二:

class Solution {public:    unordered_map<string, vector<int>> memo;    vector<int> diffWaysToCompute(string input) {        if (memo.count(input)) return memo[input];        vector<int> res;        for (int i = 0; i < input.size(); ++i) {            if (input[i] == '+' || input[i] == '-' || input[i] == '*') {                vector<int> left = diffWaysToCompute(input.substr(0, i));                vector<int> right = diffWaysToCompute(input.substr(i + 1));                for (int j = 0; j < left.size(); ++j) {                    for (int k = 0; k < right.size(); ++k) {                        if (input[i] == '+') res.push_back(left[j] + right[k]);                        else if (input[i] == '-') res.push_back(left[j] - right[k]);                        else res.push_back(left[j] * right[k]);                    }                }            }        }        if (res.empty()) res.push_back(stoi(input));        memo[input] = res;        return res;    }};

当然,这道题还可以用动态规划 Dynamic Programming 来做,但明显没有分治法来的简单,但是既然论坛里这么多陈独秀同学,博主还是要给以足够的尊重的。这里用一个三维数组 dp,其中 dp[i][j] 表示在第i个数字到第j个数字之间范围内的子串添加不同括号所能得到的不同值的整型数组,所以是个三位数组,需要注意的是我们需要对 input 字符串进行预处理,将数字跟操作分开,加到一个字符串数组 ops 中,并统计数字的个数 cnt,用这个 cnt 来初始化 dp 数组的大小,并同时要把 dp[i][j] 的数组中都加上第i个数字,通过 ops[i*2] 取得,当然还需要转为整型数。既然 dp 是个三维数组,那么肯定要用3个 for 循环来更新,这里采用的更新顺序跟之前那道 Burst Balloons 是一样的,都是从小区间往大区间更新,由于小区间之前更新过,所以我们将数字分为两部分 [i, j] 和 [j, i+len],然后分别取出各自的数组 dp[i][j] 和 dp[j][i+len],把对应的运算符也取出来,现在又变成了两个数组中任取两个数字进行运算,又整两个 for 循环,所以总共整了5个 for 循环嵌套,啊呀妈呀,看这整的,看不晕你算我输,参见代码如下:

解法三:

class Solution {public:    vector<int> diffWaysToCompute(string input) {        if (input.empty()) return {};        vector<string> ops;        int n = input.size();        for (int i = 0; i < n; ++i) {            int j = i;            while (j < n && isdigit(input[j])) ++j;            ops.push_back(input.substr(i, j - i));            if (j < n) ops.push_back(input.substr(j, 1));            i = j;        }        int cnt = (ops.size() + 1) / 2;        vector<vector<vector<int>>> dp(cnt, vector<vector<int>>(cnt, vector<int>()));        for (int i = 0; i < cnt; ++i) dp[i][i].push_back(stoi(ops[i * 2]));        for (int len = 0; len < cnt; ++len) {            for (int i = 0; i < cnt - len; ++i) {                for (int j = i; j < i + len; ++j) {                    vector<int> left = dp[i][j], right = dp[j + 1][i + len];                    string op = ops[j * 2 + 1];                    for (int num1 : left) {                        for (int num2 : right) {                            if (op == "+") dp[i][i + len].push_back(num1 + num2);                            else if (op == "-") dp[i][i + len].push_back(num1 - num2);                            else dp[i][i + len].push_back(num1 * num2);                        }                    }                }            }        }        return dp[0][cnt - 1];    }};

“C++实现添加括号的不同方式”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: C++实现添加括号的不同方式

本文链接: https://lsjlt.com/news/298431.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++实现添加括号的不同方式
    本篇内容介绍了“C++实现添加括号的不同方式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!添加括号的不同方式Given a string o...
    99+
    2023-06-20
  • C++实现LeetCode(241.添加括号的不同方式)
    [LeetCode] 241. Different Ways to Add Parentheses 添加括号的不同方式 Given a string of numbers and o...
    99+
    2024-04-02
  • Mybatis plus where添加括号方式
    目录Mybatis plus where添加括号where或and后面的条件用括号括起来Mybatis plus where添加括号 List<S...
    99+
    2024-04-02
  • C++实现验证括号的方法
    本篇内容介绍了“C++实现验证括号的方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Valid Parentheses 验证括号Given...
    99+
    2023-06-20
  • C++实现最长有效括号的方法
    这篇文章主要讲解了“C++实现最长有效括号的方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++实现最长有效括号的方法”吧!Longest Valid Parentheses 最长有效括...
    99+
    2023-06-20
  • Java C++实现相同MD5加密算法的方式
    目录Java与C++实现相同的MD5加密算法1、Java版2、C++代码3、运行效果 Java与C++实现相同的MD5加密算法 1、Java版 package com.lyz.u...
    99+
    2024-04-02
  • mysql alter添加列的实现方式
    目录mysql alter添加列alter的执行过程如下mysql基础之alter字段解读1、先创建一张表testalter_tbl2、删除,添加或修改表字段3、修改字段类型及名称4、 ALTER TABLE 对 Nul...
    99+
    2023-01-28
    mysqlalter添加列 mysqlalter alter添加列
  • C语言实现括号配对的方法示例
    本文主要介绍了C语言实现括号配对的方法示例,分享给大家,具体如下: 代码如下: #include<stdio.h> #include<string.h> ...
    99+
    2024-04-02
  • SpringCloudFeign请求添加headers的实现方式
    目录背景方案一方案二方案三方案四方案五总结背景 部门技术升级,HttpClient需要升级Feign调用,重构某一个资方时遇到请求需要添加上自定义签名headers,踩坑后记录了下来...
    99+
    2023-05-18
    Spring Cloud Feign请求 Feign请求添加headers Spring Cloud Feign
  • Objective-C不带加减号的方法实例
    前言 在Oc中,方法分为类方法和实例方法。 前置加号(+)的方法为类方法,这类方法是可以直接用类名来调用的,它的作用主要是创建一个实例。有人把它称为创建实例的工厂方法。 前置减号(-...
    99+
    2024-04-02
  • 不同的MySQL分页实现方式
    MySQL分页方法有哪些,需要具体代码示例 MySQL是一种关系型数据库管理系统,为了提高查询效率和减少数据传输量,分页查询是一个非常常见的需求。MySQL提供了多种分页方法,下面将详...
    99+
    2024-02-22
    limit offset
  • C#在Word中添加Latex数学公式和符号的方法
    本篇内容介绍了“C#在Word中添加Latex数学公式和符号的方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!注意:需要使用7.6.5版本...
    99+
    2023-06-03
  • Android实现向Launcher添加快捷方式的方法
    本文实例讲述了Android实现向Launcher添加快捷方式的方法。分享给大家供大家参考。具体如下: 当我们在应用程序Launcher的桌面空白处长按触摸时,会出现一个对话框...
    99+
    2022-06-06
    方法 launcher Android
  • Python 打印不带括号的元组的实现
    使用 str.join() 方法打印不带括号的元组,例如 result = ','.join(my_tuple)。 str.join() 方法将返回一个包含元组元素的...
    99+
    2023-05-14
    Python 打印不带括号元组 Python 打印元组
  • 对象同步:GO语言、Javascript的不同实现方式
    对象同步:GO语言、JavaScript的不同实现方式 随着计算机技术的不断发展,人们对程序性能和并发性能的要求越来越高。作为一种高效、并发性能出色的编程语言,GO语言一直备受开发者的青睐。而JavaScript作为前端开发的主流语言,也在...
    99+
    2023-09-15
    对象 同步 javascript
  • Python正则表达式实现截取成对括号的方法
    本文实例讲述了Python正则表达式实现截取成对括号的方法。分享给大家供大家参考,具体如下: strs = '1(2(3(4(5(67)6)7)8)9)0' reg1 = re.compile('([(...
    99+
    2022-06-04
    括号 方法 正则表达式
  • MySQL中有哪些不同的方式在日期中添加“半年间隔”?
    我们可以通过以下方式在日期中添加“半年间隔” -(A) 通过添加 6 个月的间隔mysql> Select '2017-06-20' + INTERVAL 6 Month AS 'After Half Year...
    99+
    2023-10-22
  • Java移除无效括号的方法实现
    目录一、题目二、示例三、解法1四、解法2一、题目 给你一个由 ‘('、')' 和小写字母组成的字符串 s。 你需要从字符串中删除最少数目的 ‘(' 或者 ‘)' (可以删除任意位置...
    99+
    2024-04-02
  • Springboot实现添加本地模块依赖方式
    目录添加本地模块依赖打包时引用外部jar包1、添加本地依赖2、同时在pom.xml的打包插件里面添加节点3、如果多个子工程里面都在lib文件夹添加了本地jar包添加本地模块依赖 这个...
    99+
    2024-04-02
  • android几种不同对话框的实现方式
    app中肯定是少不了与用户交互的各种dialog,下面给大家介绍几种提示框的提示。 一般创建一个对话框需要经过以下几步:   1、创建AlertDialog.Builder对象...
    99+
    2022-06-06
    Android
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作