.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++)
{
    
}

改成 while形式:

int n = 2;
while (true)
{
    if (!(n <= to))
        break;
    
    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)

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值