三大数组模板对比
vector模板类
- 是一个容器类和算法系统的一部分,
- 支持面向容器的操作,如排序、插入、重新排列、搜索、将数据转移到其他容器中 等。
valarray类模板
- 是面向数值计算的。
- 不是STL的一部分
- 重载了所有的算法运算符
例如将数组的每个值扩大2.5倍
- 之前STL方法
transform(ved3.begin(),ved3.end(),ved3.begin(),bind1st(multiplies<double>(),2.5));
- valarray方法
vad3 *= 2.5;
例如计算数组每个元素的自然对数
- 之前STL方法
transform(ved3.begin(),ved3.end(),ved1.begin(),log);
- valarray方法
vad1 = log(vad3);
//也可以使用
vad1 = vad3.apply(log);//可以不修改调用对象,而是返回一个包含结果的新对象
- valarray类还提供方法sum()、size()、max()、min()
- 但resize()方法不能像vector中的push_back那样自动调整大小
将STL功能应用于valarray对象。
valarray<double> vad(10);
使用数字填充数组后- valarray没有begin和end方法,所以不能这样
sort(vad.beain(),vad.end()); - vad是个对象,不是指针,因此不能像处理常规数组那样使用vad和vad+10作为区间参数。
sort(vad,vad+10) - 但是c++11提供了begin(vad) 和 end(vad)
sort(begin(vad),end(vad));
comparing vector and valarray
//===============================================================
//FileName:
// valvect.cpp
//Date:
// 2019/11/30
//Author:
// khoing(https://blog.csdn.net/qq_45391763)
//===============================================================
// valvect.cpp -- comparing vector and valarray
#include <iostream>
#include <valarray>
#include <vector>
#include <algorithm>
int main() {
using namespace std;
vector<double> data;
double temp;
cout << "Enter numbers (<=0 to quit):\n";
while (cin >> temp && temp > 0)
data.push_back(temp);
sort(data.begin(), data.end());
//------------------------------------------------------------------------
int size = data.size();
valarray<double> numbers(size);
int i;
for (i = 0; i < size; i++)
numbers[i] = data[i];
//------------------------------------------------------------------------
valarray<bool> vbool = numbers > 9;//vbool[i] 被设置为numbers[i]>9的值bool类型值,true或false
//------------------------------------------------------------------------
valarray<double> sq_rts(size);
sq_rts = sqrt(numbers);//对数组中的每个元素求平方根
//------------------------------------------------------------------------
valarray<double> results(size);
results = numbers + 2.0 * sq_rts;
//------------------------------------------------------------------------
cout.setf(ios_base::fixed);
cout.precision(4);
//------------------------------------------------------------------------
for (i = 0; i < size; i++)
{
cout.width(8);
cout << numbers[i] << ": ";
cout.width(8);
cout << results[i] << endl;
}
cout << "done\n";
return 0;
}
slice
- 参数1:起始索引
- 参数2:索引数,选择多少个元素
- 参数3:跨距,元素之间的间隔
- 例如
slice(1,4,3)
表示从1开始,跨距为3,选择4个元素,1、4、7、10
//===============================================================
//FileName:
// vslice.cpp
//Date:
// 2019/11/30
//Author:
// khoing(https://blog.csdn.net/qq_45391763)
//===============================================================
// vslice.cpp -- using valarray slices
#include <iostream>
#include <valarray>
//------------------------------------------------------------------------
const int SIZE = 12;
typedef std::valarray<int> vint; // simplify declarations
void show(const vint& v, int cols);
//------------------------------------------------------------------------
int main()
{
using std::slice; // from <valarray>
using std::cout;
vint valint(SIZE); // think of as 4 rows of 3
//------------------------------------------------------------------------
int i;
for (i = 0; i < SIZE; ++i)
valint[i] = std::rand() % 10;
cout << "Original array:\n";
show(valint, 3); // show in 3 columns
//------------------------------------------------------------------------
vint vcol(valint[slice(1, 4, 3)]); // extract 2nd column
cout << "Second column:\n";
show(vcol, 1); // show in 1 column
//------------------------------------------------------------------------
vint vrow(valint[slice(3, 3, 1)]); // extract 2nd row
cout << "Second row:\n";
show(vrow, 3);
//------------------------------------------------------------------------
valint[slice(2, 4, 3)] = 10; // assign to 2nd column
cout << "Set last column to 10:\n";
show(valint, 3);
//------------------------------------------------------------------------
cout << "Set first column to sum of next two:\n";
// + not defined for slices, so convert to valarray<int>
valint[slice(0, 4, 3)] = vint(valint[slice(1, 4, 3)])
+ vint(valint[slice(2, 4, 3)]);
show(valint, 3);
//------------------------------------------------------------------------
return 0;
}
void show(const vint& v, int cols)
{
using std::cout;
using std::endl;
int lim = v.size();
for (int i = 0; i < lim; ++i)
{
cout.width(3);
cout << v[i];
//------------------------------------------------------------------------
if (i % cols == cols - 1)
cout << endl;
else
cout << ' ';
}
//------------------------------------------------------------------------
if (lim % cols != 0)
cout << endl;
}
array类模板
- 表示长度固定的数组,因此不支持push_back 和 insert
- 但提供了多个STL方法,包括begin()、end()、rbegin()、rend()
- 所以可以很容易将STL算法用于array对象。
array<double,10> vod1,vod2,vod3
transform(vod1.begin(),vod1.end(),vod2.begin(),vod3.begin(),pluh<double>());
模板initializer_list
- 可以使用初始化里列表语法将STL容器初始化为一系列值
vector<double> payments{45.55,39.23,19.33,13}
- 其中的13可以转换为double
- 但不能窄化转换
- 如:
vector<int> value = {10,7,5.4}
- 5.4不能转换为int
//===============================================================
//FileName:
// ilist.cpp
//Date:
// 2019/11/30
//Author:
// khoing(https://blog.csdn.net/qq_45391763)
//===============================================================
// ilist.cpp -- use initializer_list
#include <iostream>
#include <initializer_list>
//------------------------------------------------------------------------
double sum(std::initializer_list<double> il);//直接传入{2,3,4}
double average(const std::initializer_list<double>& ril);
//------------------------------------------------------------------------
int main()
{
using std::cout;
cout << "List 1: sum = " << sum({ 2,3,4 })
<< ", ave = " << average({ 2,3,4 }) << '\n';
//------------------------------------------------------------------------
std::initializer_list<double> dl = { 1.1, 2.2, 3.3, 4.4, 5.5 };
cout << "List 2: sum = " << sum(dl)
<< ", ave = " << average(dl) << '\n';
//------------------------------------------------------------------------
dl = { 16.0, 25.0, 36.0, 40.0, 64.0 };
cout << "List 3: sum = " << sum(dl)
<< ", ave = " << average(dl) << '\n';
// std::cin.get();
return 0;
}
//------------------------------------------------------------------------
double sum(std::initializer_list<double> il)
{
double tot = 0;
for (auto p = il.begin(); p != il.end(); p++)
tot += *p;
return tot;
}
//------------------------------------------------------------------------
double average(const std::initializer_list<double>& ril)
{
double tot = 0;
int n = ril.size();
double ave = 0.0;
if (n > 0)
{
for (auto p = ril.begin(); p != ril.end(); p++)
tot += *p;
ave = tot / n;
}
return ave;
}