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的版本不同。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 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——大语言模型本地部署的极速利器