Разобрать вашу строку в S-выражение (хотя это обычно делается в контексте Lisp, вы можете сделать эквивалентную вещь практически на любом языке), проще всего с lex / yacc или эквивалентным, затем написать рекурсивную «производную» функцию. В диалекте OCaml-ish, что-то вроде этого:
let rec derive var = function
| Const(_) -> Const(0)
| Var(x) -> if x = var then Const(1) else Deriv(Var(x), Var(var))
| Add(x, y) -> Add(derive var x, derive var y)
| Mul(a, b) -> Add(Mul(a, derive var b), Mul(derive var a, b))
...
(Если вы не знаете синтаксис OCaml - derive
- это двухпараметрическая рекурсивная функция, в которой первый параметр - имя переменной, а второй - в последовательных строках; например, если этот параметр представляет собой структуру формы Add(x, y)
, возвращает структуру Add
, построенную из двух полей, со значениями производных x
и производных y
, и аналогично для других случаев того, что derive
может получить в качестве параметра; _
в первом шаблон означает «соответствовать чему угодно»)
После этого у вас может быть некоторая функция очистки, чтобы привести в порядок результирующее выражение (сокращение дробей и т. Д.), Но это усложняется и не является необходимым для самой деривации (то есть то, что вы получаете без нее, все еще является правильным ответом) .
Когда ваше преобразование s-exp выполнено, преобразуйте полученный s-exp в строковую форму, снова с помощью рекурсивной функции