你可以通过递归函数得到树的monomial coefficients。根据霍纳定律转换这些系数并得到一个表达式将是simple。
我可以给你一个简单的递归函数来计算这些值,即使存在一个更有效的可能。
理论知识
首先,让我们制定表达式。一个表达式E:
E = a0 + a1x + a2x^2 + ... + anx^n
可以写成 (n+1) 元组:
(a0, a1, a2, ..., an)
然后,我们定义两个操作:
-
加法:给定两个表达式E1 = (a0, ..., an)和E2 = (b0, ..., bm),E1 + E2对应的元组为:
{(a0+b0, a1+b1, ..., am+bm, a(m+1), ..., an) (n > m)
E1 + E2 = {(a0+b0, a1+b1, ..., an+bn, b(n+1), ..., bm) (n < m)
{(a0+b0, a1+b1, ..., an+bn) (n = m)
也就是说,有max(n,m)+1 元素,而ith 元素由(使用C-ish 语法)计算:
i<=n?ai:0 + i<=m?bi:0
-
乘法:给定两个表达式E1 = (a0, ..., an)和E2 = (b0, ..., bm),E1 * E2对应的元组是:
E1 * E2 = (a0*b0, a0*b1+a1*b0, a0*b2+a1*b1+a2*b0, ... , an*bm)
即有n+m+1元素,而ith元素由
计算
sigma over {ar*bs | 0<=r<=n, 0<=s<=m, r+s=i}
因此递归函数定义如下:
tuple get_monomial_coef(node)
if node == constant
return (node.value) // Note that this is a tuple
if node == variable
return (0, 1) // the expression is E = x
left_expr = get_monomial_coef(node.left)
right_expr = get_monomial_coef(node.right)
if node == +
return add(left_expr, right_expr)
if node == *
return mul(left_expr, right_expr)
在哪里
tuple add(tuple one, tuple other)
n = one.size
m = other.size
for i = 0 to max(n, m)
result[i] = i<=n?one[i]:0 + i<=m?other[i]:0
return result
tuple mul(tuple one, tuple other)
n = one.size
m = other.size
for i = 0 to n+m
result[i] = 0
for j=max(0,i-m) to min(i,n)
result[i] += one[j]*other[i-j]
return result
注意:在mul的实现中,j应该从0迭代到i,同时还必须满足以下条件:
j <= n (because of one[j])
i-j <= m (because of other[i-j]) ==> j >= i-m
因此,j 可以从 max(0,i-m) 和 min(i,n) 出发(等于 n,因为 n <= i)
C++ 实现
既然您已经有了伪代码,那么实现应该不难了。对于元组类型,一个简单的std::vector 就足够了。因此:
vector<double> add(const vector<double> &one, const vector<double> &other)
{
size_t n = one.size() - 1;
size_t m = other.size() - 1;
vector<double> result((n>m?n:m) + 1);
for (size_t i = 0, size = result.size(); i < size; ++i)
result[i] = (i<=n?one[i]:0) + (i<=m?other[i]:0);
return result;
}
vector<double> mul(const vector<double> &one, const vector<double> &other)
{
size_t n = one.size() - 1;
size_t m = other.size() - 1;
vector<double> result(n + m + 1);
for (size_t i = 0, size = n + m + 1; i < size; ++i)
{
result[i] = 0.0;
for (size_t j = i>m?i-m:0; j <= n; ++j)
result[i] += one[j]*other[i-j];
}
return result;
}
vector<double> get_monomial_coef(const Node &node)
{
vector<double> result;
if (node.type == CONSTANT)
{
result.push_back(node.value);
return result;
}
if (node.type == VARIABLE)
{
result.push_back(0.0);
result.push_back(1); // be careful about floating point errors
// you might want to choose a better type than
// double for example a class that distinguishes
// between constants and variable coefficients
// and implement + and * for it
return result;
}
vector<double> left_expr = get_monomial_coef(node.left);
vector<double> right_expr = get_monomial_coef(node.right);
if (node.type == PLUS)
return add(left_expr, right_expr);
if (node.type == MULTIPLY)
return mul(left_expr, right_expr);
// unknown node.type
}
vector<double> get_monomial_coef(const Tree &tree)
{
return get_monomial_coef(tree.root);
}
注意:此代码未经测试。它可能包含错误或错误检查不足。确保你理解它并自己实现它,而不是复制粘贴。
从这里开始,您只需要根据此函数为您提供的值构建一个表达式树。