SGI专属power(),iota()方法

// file: 6numeric.cpp
#include <numeric>
#include <vector>
#include <fucntional>
#include <iostream>
#include <iterator> // ostream_iterator
#include <algorithm>

using namespace std;

int main()
{
    int ia[5] = {1,2,3,4,5};
    vector<int> iv(ia,ia+5);
    cout << accumulate(iv.begin(),iv.end(),0) << endl;
    // 15,i.e. 0 + 1 + 2 + 3 + 4 + 5

    cout << accumulate(iv.begin(),iv.end(),0,minus<int>()) << endl;
    // -15,i.e. 0 - 1 - 2 - 3 - 4 - 5

    cout << inner_product(iv.begin(),iv.end(),iv.begin(),10) << endl;
    // 65,i.e 10 + 1*1 + 2*2 + 3*3 + 4*4 + 5*5

    cout << inner_product(iv.begin(),iv.end(),iv.begin(),10,minus<int>(),plus<int>()) << endl;
    // -20,i.e. 10 - 1+1 - 2+2 - 3+3 - 4+4 - 5+5

    // 以下的这个迭代器将绑定到cout,作为输出用
    ostream_iterator<int> oite(cout," ");

    partial_sum(iv.begin(),iv.end(),oite);
    // 1 3 6 10 15 (第n个元素是前n个元素的相加总计)

    partial_sum(iv.begin(),iv.end(),oite,minus<int>());
    // 1 -1 -4 -8 -13 (第n个新元素是前n个旧元素的运算总计)

    adjacent_difference(iv.begin(),iv.end(),oite);
    // 1 1 1 1 1 (#1元素照录,#n新元素等于#n旧元素 - #n-1旧元素)

    adjacent_difference(iv.begin(),iv.end(),oite,plus<int>());
    // 1 3 5 7 9 (#1元素照录,#n新元素等于op(#n旧元素,#n-1旧元素))

    cout << power(10,3) << endl;                // 1000 ,i.e 10*10*10
    cout << power(10,3,plus<int>()) << endl;    // 30,i.e,10+10+10

    int n = 3;
    iota(iv.begin(),iv.end(),n);        // 在指定区间内填入n,n+1,n+2...
    for (int i=0; i < iv.size(); ++ i)
        cout << iv[i] << ' ';   // 3 4 5 6 7
    return 0;
}

这段代码摘自是《STL源码剖析》P298,但是无法通过编译,编译错误有2个
\P298\main.cpp||In function 'int main()':|
\P298\main.cpp|42|error: 'power' was not declared in this scope|
\P298\main.cpp|46|error: 'iota' was not declared in this scope|
\P298\main.cpp|47|warning: comparison between signed and unsigned integer expressions|
||=== Build finished: 2 errors, 1 warnings ===|
警告是很显然的,因为类型不匹配,如果将int转换成size_t就没有任何问题,这不是问题。
第一个错误:power没有声明,我们知道c语言中power的头文件是math.h,在C++中我们应该这么写#include <cmath>,我将#include <cmath> 加入代码中还是错的。很明显这里power的参数有仿函数,因此头文件显然不应该是cmath。于是乎我谷歌了一下还是没有结果,我就傻了,莫非他不是STL之中的函数,我在《STL源码剖析》目录中找到了power的那一节。
一看书我就知道了:
“power算法由SGI专属,不在STL标准之列。它用来计算某数的n幂次方。...”
之后的一节便是 :“iota算法由SGI专属,并不在STL标准之列。它用来设定某个区间的内容,时期内的每一个元素从指定的value值开始,呈现递增状态。”

 这时候我才明白了,原来是这么回事!我还纳闷呢,听过"itoa",还没听过"iota",我还怀疑是书写错了。
 那好吧,既然没定义,那就自定义一个吧,再说书上有源码,直接超过去就ok了。
下面是程序的最终版:

// file: 6numeric.cpp
#include <numeric>
#include <vector>
#include <functional>
#include <iostream>
#include <iterator> // ostream_iterator
#include <algorithm>
using namespace std;

// 版本2,幂次方,如果指定为乘法运算,则当n >= 0时返回x^n
// 注意,“MonoidOperation”必须满足结合律(associative)
// 但不需满足交换律
template <class T,class Interger,class MonoidOperation>
T power(T x,Interger n,MonoidOperation op) {
    if (n == 0)
        // return identity_element(op);    // 取出“证同元素”identity element
        // 张杰注释:以上代码error: 'identity_element' was not declared in this scope|
        // 可能也是版本的问题。因此,我就直接return x了,这不合理,但是我没有找到合理的解决方案
        return x;
    else {
        while ((n&1) == 0) {
            n >>= 1;
            x = op(x,x);
        }
        T result = x;
        n >>= 1;
        while (n != 0) {
            x = op(x,x);
            if ((n & 1) != 0)
                result = op(result,x);
            n >>= 1;
        }
        return result;
    }
}

// 版本1,乘幂
template <class T,class Integer>
inline T power(T x,Integer n) {
    return power(x,n,multiplies<T>());  //指定运算型为乘法
}

// 函数意义:在[first,last)区间内填入value,value+1,value+2
template <class ForwardIterator,class T>
void iota(ForwardIterator first,ForwardIterator last,T value) {
    while (first != last)
        * first ++ = value ++;
}
int main()
{
    int ia[5] = {1,2,3,4,5};
    vector<int> iv(ia,ia+5);
    cout << accumulate(iv.begin(),iv.end(),0) << endl;
    // 15,i.e. 0 + 1 + 2 + 3 + 4 + 5

    cout << accumulate(iv.begin(),iv.end(),0,minus<int>()) << endl;
    // -15,i.e. 0 - 1 - 2 - 3 - 4 - 5

    cout << inner_product(iv.begin(),iv.end(),iv.begin(),10) << endl;
    // 65,i.e 10 + 1*1 + 2*2 + 3*3 + 4*4 + 5*5

    cout << inner_product(iv.begin(),iv.end(),iv.begin(),10,minus<int>(),plus<int>()) << endl;
    // -20,i.e. 10 - 1+1 - 2+2 - 3+3 - 4+4 - 5+5

    // 以下的这个迭代器将绑定到cout,作为输出用
    ostream_iterator<int> oite(cout," ");

    partial_sum(iv.begin(),iv.end(),oite);
    cout << endl;   // 此行代码由张杰添加,便于显示
    // 1 3 6 10 15 (第n个元素是前n个元素的相加总计)

    partial_sum(iv.begin(),iv.end(),oite,minus<int>());
    cout << endl;   // 此行代码由张杰添加,便于显示
    // 1 -1 -4 -8 -13 (第n个新元素是前n个旧元素的运算总计)

    adjacent_difference(iv.begin(),iv.end(),oite);
    cout << endl;   // 此行代码由张杰添加,便于显示
    // 1 1 1 1 1 (#1元素照录,#n新元素等于#n旧元素 - #n-1旧元素)

    adjacent_difference(iv.begin(),iv.end(),oite,plus<int>());
    cout << endl;   // 此行代码由张杰添加,便于显示
    // 1 3 5 7 9 (#1元素照录,#n新元素等于op(#n旧元素,#n-1旧元素))

    cout << power(10,3) << endl;                // 1000 ,i.e 10*10*10
    cout << power(10,3,plus<int>()) << endl;    // 30,i.e,10+10+10

    int n = 3;
    iota(iv.begin(),iv.end(),n);        // 在指定区间内填入n,n+1,n+2...
    for (int i=0; i < iv.size(); ++ i)
        cout << iv[i] << ' ';   // 3 4 5 6 7
    cout << endl;   // 此行代码由张杰添加,便于显示
    return 0;
}
备注:
1、以上代码我进行修改的地方,都进行了注释,其他代码全部摘自侯捷《STL源码剖析》
2、以上代码通过code::blocks编译运行。其他IDE结果可能有所不同,其原因可能是因为STL的版本不同。
本文完
转载请表明出处,谢谢
2010-08-19

转载于:https://www.cnblogs.com/chinazhangjie/archive/2010/08/19/1803716.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值