如果我有一个表达式,例如x * x * x,则存储在如下数据结构中:mult(var x,mult(var x,var x))
我想实现一个函数来递归地区分方程(所以3 * x * x或x * x +(x + x)* x等,不需要简化),任何建议如何成为这个?< / p>
答案 0 :(得分:2)
您会找到匹配的差异规则并应用它。例如,在这种情况下,我们有规则(其中A和B代表整个子表达式)
var textEdit = new UITextField (new CGRect (15, 100, 200, 30));
textEdit.Enabled = false;
textEdit.Text = "Hello from Xamarin";
var xamImageView = new UIImageView (new CGRect (0,0, 25, 25));
xamImageView.Image = UIImage.FromBundle ("xamagon");
textEdit.RightView = xamImageView;
textEdit.TextAlignment = UITextAlignment.Right;
textEdit.RightViewMode = UITextFieldViewMode.Always;
textEdit.BorderStyle = UITextBorderStyle.None;
此规则的左侧与我们设置
时的公式匹配diff(mult(A, B)) -> add(mult(diff(A),B), mult(A, diff(B)))
因此我们可以将此规则应用于公式并获取
A = var x
B = mult(var x, var x)
现在对剩余的差异操作进行递归处理。
您需要的另一条规则是:
diff(mult(var x, mult(var x, var x))) ->
add(mult(diff(var x),mult(var x, var x)), mult(var x, diff(mult(var x, var x))))
答案 1 :(得分:2)
请注意指出语言会有所不同。 Lisp特别适合这个问题。
(defun d (f x)
(etypecase f
(number 0)
(symbol (if (eq f x) 1 0))
(list (df (first f) (rest f) x))))
(defun df (op args x)
(let ((a (first args))
(b (second args)))
(case op
((+ -) `(,op ,(d a x) ,(d b x)))
(* `(+ (* ,a ,(d b x)) (* ,(d a x) ,b)))
(/ `(/ (- (* ,(d a x) ,b) (* ,a ,(d b x))) (^ ,b 2)))
(^ `(* (* ,b (^ ,a ,(1- b))) ,(d a x)))
(sin `(* (cos ,a) ,(d a x)))
(cos `(* (- (sin ,a)) ,(d a x))))))
Lisp喜欢前缀表示法。这相当于表达式的抽象语法树。二进制操作看起来像(op lhs rhs)
。所以要区分(3 sin(x^2))^2
,
> (d '(^ (* (sin (^ x 2)) 3) 2) 'x)
(* (* 2 (^ (* (SIN (^ X 2)) 3) 1))
(+ (* (SIN (^ X 2)) 0) (* (* (COS (^ X 2)) (* (* 2 (^ X 1)) 1)) 3)))
这是一个正确的答案,但显然它远非简单的形式。所以下一步是添加表达式简化器。有一个非常简陋的,
> (simplify (d '(^ (* (sin (^ x 2)) 3) 2) 'x))
(* (* 2 (* (SIN (^ X 2)) 3)) (* (* (COS (^ X 2)) (* 2 X)) 3))
使用中缀表示法,这是2(3 sin(x^2)) (3 cos(x^2) (2x))
。显然,可以进行更多的简化,但最简单的是#34;通过任何有用的定义是一个复杂的主题。