LeetCode-241题-C语言实现
作者:互联网
1. 原题题目
【题目来源:LeetCode第241题】给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果。你需要给出所有可能的组合的结果。有效的运算符号包含 +, - 以及 * 。
如给定字符串: 2+1-1,有如下两种计算方法 ((2+1)-1) = 2 和 (2+(1-1)) = 2,则程序输出结果应该是[2,2]
2 题目分析
由于原问题比较复杂,因此考虑能不能采用递归思想将其简化。以操作符为分界,可以将表达式字符串分为两个部分,问题就变成求解两个更为简单的字符串的可能取值,于是问题便得到简化。最终结果就是两个部分的解分别执行相应的运算。
整个递归过程如下:
- 若字符串表达式全部由数字构成,则将其转为整形数并且返回。
- 若不是全部由数字构成,则进行递归处理直到满足递归出口条件,并且计算两个部分的可能取值。
仍然采用 2+1-1为例, 以操作符为分界,将表达式字符串分成两个部分共有如下两种分法:
- 以 + 分界,可分为 2 和 1-1 两部分,前半部分直接返回 2,后半部分继续递归处理又可以分为 1 和 1 两部分,由于满足递归出口条件则直接返回 1 和 1,并计算 1-1 = 0,最后计算 2+0 = 2
- 以 - 分界,可分为 2+1 和 1 两部分,前半部分继续递归处理又可以分为 2 和 1 两部分,由于满足递归出口条件则直接返回 2 和 1,并计算 2+1 = 3,后半部分直接返回 1, 最后计算 3-1 = 2
3 代码实现
题目要求采用malloc进行空间申请,并且返回其地址,返回数据的个数由函数的指针参数进行接收,其原型如下:int* diffWaysToCompute(char* expression, int* returnSize)
完整代码如下:
// 根据操作数和操作符进行相应计算
int calc(int num1, int num2, char op)
{
if (op == '+')
return num1 + num2;
else if (op == '-')
return num1 - num2;
else
return num1 * num2;
}
// 判断一个字符是不是数字字符
int isnum(char c1)
{
return (c1 >= '0' && c1 <= '9');
}
// 判断一个字符是不是操作符
int isop(char* c1)
{
return *c1 == '+' || *c1 == '-' || *c1 == '*';
}
/*
该函数为真正的实现过程,exp-字符串表达式, len-表达式长度 retsize -接收结果个数
*/
int* diffWaysToCompute1(char* exp, int len, int* retsize)
{
int icnt = 0;
int* res = NULL;
int index = 0;
int retsize1 = 0;
int retsize2 = 0;
res = (int*)malloc(sizeof(int));
// 若全是数字,则直接返回
while (icnt < len)
{
if (!isnum(*(exp + icnt))) break;
icnt++;
}
if (icnt == len)
{
*res = atoi(exp);
*retsize = 1;
}
else
{
for (int i = 0; i < len; i++) // 遍历字符串,根据运算符对字符串进行分割
{
if (isop(exp + i)) // 若是运算符则进行切分并递归
{
int* res1 = diffWaysToCompute1(exp, i, &retsize1); // 递归计算左半字符串
int* res2 = diffWaysToCompute1(exp + i + 1, len - i - 1, &retsize2); // 递归计算右半字符串
// 根据左右表达式串的结果重新申请空间,用realloc是因为需要将之前循环中产生的最终结果进行保存
int* tmp = (int*)realloc(res, (index + retsize1 * retsize2) * sizeof(int));
res = tmp;
for (int m = 0; m < retsize1; m++)
{
for (int n = 0; n < retsize2; n++)
{
res[index++] = calc(res1[m], res2[n], exp[i]); //计算表达式
}
}
free(res1); // res1和res2是在上一层递归中malloc申请的,使用完释放
free(res2);
}
}
*retsize = index; // 返回最终结果个数
}
return res;
}
int* diffWaysToCompute(char* expression, int* returnSize) {
//之所以采用添加长度参数的diffWaysToCompute1进行递归,主要是为了节省内存空间
return diffWaysToCompute1(expression, strlen(expression), returnSize);
}
注: 代码中没有考虑表达式不合法的情况,默认输入的表达式是合法的
标签:return,递归,int,C语言,241,exp,字符串,LeetCode,表达式 来源: https://blog.csdn.net/Nothing249/article/details/122697357