1. 程式人生 > >C++STL 中的線性容器整體/逐元素操作方法 少寫80%for循環

C++STL 中的線性容器整體/逐元素操作方法 少寫80%for循環

個數 multipl 頭文件 turn 含義 enc function thead gcd

本文中示例代碼默認已引用 std 命名空間

累加 (std::accumulate)

accumulate(begin, end, init, op)

返回給定區間內元素的累加值與給定初值的和,初值不可省略

可指定求和運算,默認為std::plus

vector<int>vec = {1, 2, 3, 4};
cout<<accumulate(vec.begin(), vec.end(), 0); 
//累加, 輸出: 10
cout<<accumulate(vec.begin(), vec.end(), 1, bit_xor<int>());
//異或和,輸出: 5

運算操作函數對象見 functional 頭文件,常用如下

函數對象 含義
multiplies 乘法
bit_xor 按位異或
bit_and 按位與

?

前綴和 (std::partial_sum)

partial_sum(begin, end, res)

計算給定區間的前綴和,存入res (iterator)中,可以直接存入原容器

int a[5] = {1, 2, 3, 4, 5};
partial_sum(a, a+5, a); 
// a : {1, 3, 6, 10, 15}

?

遞增填充 (std::iota)

iota(begin, end, value)

遞增填充給定區間,即

*(d_first)   = value;
*(d_first+1) = ++value;
...

示例:

vector<int>vec;
vec.resize(10);
iota(vec.begin(), vec.end(), 0);
//vec: {0, 1, 2, ..., 9}

?

定值填充 (std::fill)

fill(begin, end, val)

填充給定區間為val

fill_n(begin, n, val)

指定區間起點和長度

?

生成值填充 (std::generate)

generate(begin, end, func)
generate_n(begin, n, func)

使用函數生成給定區間的值

int a[10];
generate(a, a+5, read);

其中 read 函數可以為

int read(){
    int ret;
    scanf("%d", &ret);
    return ret;
}

配合讀入優化可以一行代碼讀取數據,免去寫 for 循環了

此外還可以用來隨機數填充等等

?

逐元素函數操作 (std::for_each)

for_each(begin, end, func)

對區間內的元素執行一元函數 func

int a[5] = {1, 2, 3, 4, 5};
for_each(a, a+5, [](int &x){ x&=1; });
//a : {1, 0, 1, 0, 1}

感覺非常有用,配合 lambda 比寫 for 循環舒服多了,應用場景非常廣泛

?

逐元素函數計算 (std::transform)

transform(begin, end, res, func)

對區間內的元素執行一元函數 func ,將返回值存到 res (也是 iterator)中

可以直接存入原容器

int a[5] = {1, 2, 3, 4, 5};
transform(a, a+5, a, [](int x) { return __gcd(x, 2); });
//a : {1, 2, 1, 2, 1}

?

計數與條件計數 (std::count & std::count_if)

count(begin, end, value)

計數區間內值為 value 的元素個數

count_if(begin, end, func)

計數區間內滿足條件的元素個數,func 為一元謂詞

int a[5] = {1, -1, 2, -2, 3};
cout<<count(a, a+5, 2); 
//輸出 : 1
cout<<count_if(a, a+5, [](int x) { return x>0; });
//輸出 : 3

?

感覺有了這些 STL 幾乎就不再用寫那種只有一兩句循環體的 for 循環了...

C++STL 中的線性容器整體/逐元素操作方法 少寫80%for循環