游戏开发论坛

 找回密码
 立即注册
搜索
查看: 16808|回复: 48

介绍一种强大的For函数

[复制链接]

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2010-12-1 01:02:00 | 显示全部楼层 |阅读模式
template <class T, class FAdd, class FElem> T For(int from, int to, FAdd fAdd, FElem fElem)
{
    assert(to >= from);
    T sum = fElem(from);
    for (int i = from + 1; i <= to; i++)
        sum = fAdd(sum, fElem(i));
    return sum;
}

数学上面我们常看到这样的符号,比如:

这两个分别是求一串式子的和,和一串的集合的并。

类似地,我们可以从求和、求并,推广到任意的二参数运算(或二参数函数)

比如推广到字符串加


再比如更复杂的,字符串之间以 "," 相连,例如我们要生成一个表示一个数组的字符串,
例如 to_str(x[0]) + "," + to_str(x[1]) + "," +  ... + "," + to_str(x[n-1])


这个计算,用我们在本文开头定义的 For 函数可以写成:
str add(str a, str b) { return a + "," + b; }
For(0, n-1, add, [](int i){ return to_str(x); })
// 或者:
For(0, n-1, [](str a, str b) { return a + "," + b; }, [](int i) { return to_str(x); })

PS. 有时候考虑到性能,我们还可以有一种变种版本:

template <class T, class F> T For(int from, int to, T sum0, F f)
{
    if (to < from)
        return sum0;

    T sum = sum0;
    for (int i = from; i <= to; i++)
        sum = f(sum, i);
    return sum;
}

这里的 f 就是上面的 fAdd(求和) 和 fElem(求第i个元素) 的复合函数,
比如上面的那个计算可以改写成:
For(0, n-1, "", [](ptr<str> pSum, int i) { *pSum += to_str(x); return pSum; })

不过必须注意,这种情况下,参数 sum0 必须为你那个(T上的)"加法"运算的"单位元",或者是被"加"的第一个元素。
举个典型的例子,计算 a[0] * a[1] * ... * a[n-1]
如果写成 For(0, n-1, 0, [](float product, int i) { return product * a; })
这样就错了!
应当写成 For(0, n-1, 1, [](float product, int i) { return product * a; }),
或者 For(1, n-1, a[0], [](float product, int i) { return product * a; }).

30

主题

422

帖子

433

积分

中级会员

Rank: 3Rank: 3

积分
433
发表于 2010-12-1 11:02:00 | 显示全部楼层

Re:介绍一种强大的For函数

from,to,i++扩展为from,to,step岂不是更强大?也不必要求step为正,只要非0即可。

57

主题

139

帖子

141

积分

注册会员

Rank: 2

积分
141
发表于 2010-12-1 13:02:00 | 显示全部楼层

Re:介绍一种强大的For函数

这是什么语言?

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
 楼主| 发表于 2010-12-2 01:51:00 | 显示全部楼层

Re: Re:介绍一种强大的For函数

kaikai: Re:介绍一种强大的For函数

from,to,i++扩展为from,to,step岂不是更强大?也不必要求step为正,只要非0即可。


那你怎么不说用汇编呢?
这种 For 函数用起来十分方便,代码也简洁,还非常不容易出错。

step 简直是鸡肋!C++那种也不是必要的。
数学里面的 Σ 语法中根本没有 step, 因为可以在项的表达式中用函数表达step!
如果你去支持step,你就会发现它可以和并在被"加"项的表达式里(函数合成)。
比如 求 sin(a[0]) + sin(a[2]) + sin(a[4]) + ... + sin(a[n])
写成 Σ[i'=0..n/2] sin(a[i' * 2]) 就可以了。这里 i' 就是 step 为 2 的 i. 即 i = i' * 2

用我们的C++中的For函数就是:
For(1, n, [](int a, int b) { return a + b; }, [](int _i) { return sin(a[_i * 2]) })

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
 楼主| 发表于 2010-12-2 01:52:00 | 显示全部楼层

Re: Re:介绍一种强大的For函数

aaaadddd: Re:介绍一种强大的For函数

这是什么语言?


[](x) { return f(x); }

这个是C++的lambda表达式,你也可以用boost的lambda, 或者用"函数对象".

45

主题

1163

帖子

1165

积分

金牌会员

Rank: 6Rank: 6

积分
1165
发表于 2010-12-2 09:06:00 | 显示全部楼层

Re:介绍一种强大的For函数

问:有一个常量数组 const int array[] = {1,2,3,4,5,6,7,8,9}; 写程序求这个数组所有元素的和,程序中不许出现 for, while, do. + 只能出现一次. 不允许借助标准库和任何其它库或API.

11

主题

1238

帖子

1782

积分

金牌会员

Rank: 6Rank: 6

积分
1782
发表于 2010-12-2 20:04:00 | 显示全部楼层

Re:介绍一种强大的For函数

楼上你写啊,写不出来你就是猪头

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
 楼主| 发表于 2010-12-2 20:28:00 | 显示全部楼层

Re: Re:介绍一种强大的For函数

小小C: Re:介绍一种强大的For函数

问:有一个常量数组 const int array[] = {1,2,3,4,5,6,7,8,9}; 写程序求这个数组所有元素的和,程序中不许出现 for, while, do. + 只能出现一次. 不允许借助标准库和任何其它库或API.


  int sum = 0, i = 0;
Line1:
  if (i < 9)
  {
    sum = sum + array;
    goto Line1;
  }

45

主题

1163

帖子

1165

积分

金牌会员

Rank: 6Rank: 6

积分
1165
发表于 2010-12-3 09:00:00 | 显示全部楼层

Re:介绍一种强大的For函数

忘了说不能用 goto!
一种答案

template<int TNum, typename TClass>
class SumArray
{
public:
        static TClass Result( const TClass * pArray )
        {
                return pArray[TNum-1] + SumArray<TNum-1, TClass>::Result( pArray );
        }
};

template<typename TClass>
class SumArray<1, TClass>
{
public:
        static TClass Result( const TClass * pArray )
        {
                return pArray[0];
        }
};

        const int c_array[] = {1,2,3,4,5,6,7,8,9};
        cout << SumArray<9, int>::Result( c_array ) << endl;

11

主题

1238

帖子

1782

积分

金牌会员

Rank: 6Rank: 6

积分
1782
发表于 2010-12-3 20:20:00 | 显示全部楼层

Re:介绍一种强大的For函数

用递归不就得了!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-8-17 08:55

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表