2011-10-08 61 views
6

我有一个很长的表达式,我想将其分解为一组术语。例如说我有:将表达式拆分为术语集合

a + b - c + d + 4*e - 3*f 

我想加法/减法分割表达式为:

{a, b, -c, d, 4*e, -3*f} 

我对这种动机是,我要处理的项原始表达式项。这可能吗?

编辑:给出的例子与我在Mathematica中处理的相比非常简单,只是我不确定如何在这里写数学。

回答

9

要拆分表达式,您需要使用LevelLevel为您提供了子表达式的列表,您可以指定您希望返回子表达式的级别。在这种情况下,你需要levelspec 1.

In[1]:= expr = a + b - c + d + 4 e - 3 f; 
In[2]:= Level[expr, 1] 

Out[2]= {a, b, -c, d, 4 e, -3 f} 

一个稍微更复杂的表达一个例子:

In[3]:= expr2 = a^2 + 5 bc/ef - Sqrt[g - h] - Cos[i]/Sin[j + k]; 
In[4]:= Level[expr2, 1] 

Out[4]= {a^2, (5 bc)/ef, -Sqrt[g - h], -Cos[i] Csc[j + k]} 
4

您可能还可以使用MonomialList,如果你的表达是多项式:

In[56]:= MonomialList[a + b - c + d + 4*e - 3*f] 

Out[56]= {a, b, -c, d, 4 e, -3 f} 

(非多项式,如Yoda的expr2不工作)。

4

由于没有人提到它,相当于Yoda的Level[expr, 1]建设是使用ApplyList更换一个表达式的头部:

In[1]:= expr = a + b - c + d + 4 e - 3 f; 

In[2]:= List @@ expr 
     Level[expr, 1] == % 

Out[2]= {a, b, -c, d, 4 e, -3 f} 
Out[3]= True 


In[4]:= expr2 = a^2 + 5 bc/ef - Sqrt[g - h] - Cos[i]/Sin[j + k]; 

In[5]:= List @@ expr2 
     Level[expr2, 1] == % 

Out[5]= {a^2, (5 bc)/ef, -Sqrt[g - h], -Cos[i] Csc[j + k]} 
Out[6]= True 

这两种方法基本上做同样的事情,并具有相同的时序(使用我的版本average timing function的)

In[1]:= SetOptions[TimeAv, Method -> {"MinNum", 80000}, "BlockSize" -> 20000]; 

In[7]:= List @@ expr // TimeAv 

Total wall time is 0.244517, total cpu time is 0.13 
and total time spent evaluating the expression is 0.13 

The expression was evaluated 80000 times, in blocks of 20000 runs. This yields 
a mean timing of 1.625*10^-6 with a blocked standard deviation of 2.16506*10^-7. 

Out[7]= {1.625*10^-6, {a, b, -c, d, 4 e, -3 f}} 

In[8]:= Level[expr, 1] // TimeAv 

Total wall time is 0.336927, total cpu time is 0.16 
and total time spent evaluating the expression is 0.16 

The expression was evaluated 80000 times, in blocks of 20000 runs. This yields 
a mean timing of 2.*10^-6 with a blocked standard deviation of 3.53553*10^-7. 

Out[8]= {2.*10^-6, {a, b, -c, d, 4 e, -3 f}} 
3

您还可以使用Replace

In[65]:= Replace[a + b - c + d + 4*e - 3*f, HoldPattern[Plus[a___]] :> {a}] 

Out[65]= {a, b, -c, d, 4 e, -3 f} 

您需要使用HoldPattern(或等同的一些技巧),以防止Plus[a__]从评估到a__,其中有只包裹在一个列表中的第一个参数,而不是创建的参数列表Plus结果。

+3

规则的另一种可能性是'Plus [a_,b___]:> {a,b}' – Simon

+1

如果有人赞成'Replace',则可以将其与'Apply'组合为另一个选项:'Replace [a + b - c + d + 4 * e - 3 * f,a_Plus:> List @@ a]'或者,也许:'替换[a + b - c + d + 4 * e - 3 * f,Plus - > List,1 ,头 - >真]' –