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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// 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;
}
// 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;
}

这段代码摘自是《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了。
下面是程序的最终版:

备注:
1、以上代码我进行修改的地方,都进行了注释,其他代码全部摘自侯捷《STL源码剖析》
2、以上代码通过code::blocks编译运行。其他IDE结果可能有所不同,其原因可能是因为STL的版本不同。
本文完
转载请表明出处,谢谢
2010-08-19
posted @   独酌逸醉  阅读(1258)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
点击右上角即可分享
微信分享提示