1 条题解
-
0
题意分析
这段代码实现了一个符号求导系统,可以对输入的数学表达式进行求导运算。支持的运算包括:
- 基本运算:加法(
+
)、减法(-
)、乘法(*
)、除法(/
)。 - 函数运算:自然对数(
ln
)。 - 变量:仅支持变量
x
。 - 常数:如
5
、-3.14
等数字。
输入:一个合法的数学表达式字符串(如
x+5
、ln(x)
)。
输出:该表达式的导数(如1+0
、(1)/(x)
)。解题思路
-
表达式解析:
- 使用递归下降法(Recursive Descent Parsing)分解表达式。
- 根据运算符优先级(
+
/-
<*
//
<(
/ln
)拆分表达式。
-
求导规则:
- 常数:导数为
0
。 - 变量
x
:导数为1
。 - 加法/减法:
(u±v)' = u' ± v'
。 - 乘法:
(u*v)' = u'*v + u*v'
。 - 除法:
(u/v)' = (u'*v - u*v') / v^2
。 - 自然对数:
(ln(u))' = u' / u
。
- 常数:导数为
-
优化输出:
- 合并连续的
+-
(如1+-2
→1-2
)。 - 去除多余的括号(如
((x))
→x
)。
- 合并连续的
代码
#include <iostream> #include <string> #include <stack> #include <cctype> using namespace std; // 辅助函数:判断是否为数字 bool is_number(const string &s) { if (s.empty()) return false; size_t i = 0; if (s[0] == '-' || s[0] == '+') i++; bool has_digit = false; bool has_dot = false; for (; i < s.size(); i++) { if (s[i] == '.') { if (has_dot) return false; has_dot = true; } else if (!isdigit(s[i])) { return false; } else { has_digit = true; } } return has_digit; } // 主求导函数 string derive(const string &expr) { // 基础情况 if (expr == "x") return "1"; if (is_number(expr)) return "0"; // 处理括号表达式 if (expr.size() >= 3 && expr[0] == '(' && expr.back() == ')') { string inner = expr.substr(1, expr.size()-2); // 检查是否是ln函数 if (inner.size() > 3 && inner.substr(0, 3) == "ln(" && inner.back() == ')') { string arg = inner.substr(3, inner.size()-4); string d_arg = derive(arg); return "(" + d_arg + ")/(" + arg + ")"; } // 解析运算符 int op_pos = -1; int paren_level = 0; for (int i = 0; i < inner.size(); ++i) { char c = inner[i]; if (c == '(') paren_level++; else if (c == ')') paren_level--; else if (paren_level == 0 && (c == '+' || c == '-' || c == '*' || c == '/')) { op_pos = i; break; } } if (op_pos != -1) { char op = inner[op_pos]; string left = inner.substr(0, op_pos); string right = inner.substr(op_pos+1); string d_left = derive(left); string d_right = derive(right); switch (op) { case '+': return "(" + d_left + "+" + d_right + ")"; case '-': return "(" + d_left + "-" + d_right + ")"; case '*': return "(" + d_left + "*" + right + "+" + left + "*" + d_right + ")"; case '/': return "(" + d_left + "*" + right + "-" + left + "*" + d_right + ")/" + right + "^2"; } } } return "0"; // 默认情况 } int main() { string line; while (getline(cin, line)) { cout << derive(line) << endl; } return 0; }
- 基本运算:加法(
- 1
信息
- ID
- 468
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 8
- 已通过
- 1
- 上传者