.Net4 Expression Tree 入门(4): 求N以内的所有质数

 

目录

.Net4 Expression Tree 入门(1): Hello World!

.Net4 Expression Tree 入门(2): IfThen, SwitchCase

.Net4 Expression Tree 入门(3): Loop 循环

 

前面已经介绍了.Net4 Expression Tree的分支与循环,是时候综合起来写一个稍微复杂一点的实例了。

求N以内的所有质数

一般的写法
static List<int> GetPrimes_SimpleMethod(int to)
{
    var res = new List<int>();
    for (int n = 2; n <= to; n++)
    {
        bool found = false;

        for (int d = 2; d <= Math.Sqrt(n); d++)
        {
            if (n % d == 0)
            {
                found = true;
                break;
            }
        }

        if (!found)
            res.Add(n);
    }
    return res;
}

 

暂且不用考虑以上算法的时间复杂度、性能什么的,因为只是为了学习 Expression Tree 而已。之前都说过,Expression 里是没有For这些常用方法的,只有Loop,因此为了更方便构造 Expression Tree, 需要对上面代码稍微修改成没for的形式。

for (int n = 2; n <= to; n++)
{
    // do sth…
}

改成 while形式:

int n = 2;
while (true)
{
    if (!(n <= to))
        break;
    // do sth…
    n++;
}
求N以内的所有质数的“NoFor” 写法

【纯粹是为了更方便构造 Expression Tree,否则相信没人用while(true)这样写法】

static List<int> GetPrimes_NoFor(int to)
{
    var res = new List<int>();
    int n = 2;
    while (true)
    {
        if (!(n <= to))
            break;
        bool found = false;

        int d = 2;
        while (true)
        {
            if (!(d <= Math.Sqrt(n)))
                break;

            if (n % d == 0)
            {
                found = true;
                break;
            }

            d++;
        }

        if (!found)
            res.Add(n);

        n++;
    }
    return res;
}

 

上述代码与表达式的对比列表

原始代码

表达式

var res = new List<int>();
Expression.Assign(
    res,
    Expression.New(typeof(List<int>))
)
int n = 2;
Expression.Assign(
    n,
    Expression.Constant(2)
)
while (true)
{
    if (!(n <= to))
        break;
Expression.Loop(
    Expression.Block(
        Expression.IfThen(
            Expression.Not(
                Expression.LessThanOrEqual(
                    n,
                    to
                )
            ),
            Expression.Break(breakOuter)
        )
Math.Sqrt(n)
Expression.Call(
    null,
    typeof(Math).GetMethod("Sqrt"),
    Expression.Convert(
        n,
        typeof(double)
    )
)
d++;
Expression.PostIncrementAssign(d)
res.Add(n);
Expression.Call(
    res,
    typeof(List<int>).GetMethod("Add"),
    n
)

 

最终构建表达式的代码很长,有兴趣的不妨自己试着写写,这里不贴上来,可以参考这篇外文STATEMENT TREES WITH LESS PAIN – FOLLOW-UP ON SYSTEM.LINQ.EXPRESSIONS V4.0》。

你是否也因为Expression 里没有for这个方法而感到不爽?一切循环都得改成loop这种形式?Expression构建是不是很麻烦罗嗦?为什么Expression一切方法皆是static的…等等。

如果改成下面这种形式会不会好点?

原始代码

表达式

var res = new List<int>();
res.Assign(Expression.New(typeof(List<int>)))
int n = 2;
n.Assign(2)
n ++;
n.PostIncrementAssign()
for (int n = 2; n <= to; n++)
Expression.For(n, n.Assign(2), n <= to, n.PostIncrementAssign()
res.Add(n); res.Method("Add", n)

 

这样会不会更简洁?欢迎作进一步交流。我会在下一篇随笔里分析如何实现以上形式的写法。


作者:Bruce编程的艺术世界
出处:http://coolcode.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

posted on 2010-05-26 14:59  CoolCode  阅读(2756)  评论(0编辑  收藏  举报