日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

C++拾取——使用stl标准库生成等差、等比数列的方法

發(fā)布時間:2023/11/27 生活经验 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++拾取——使用stl标准库生成等差、等比数列的方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

? ? ? ? 代碼是思想的表達(dá)。閱讀代碼是一個猜測、求證的過程。這個過程非常費腦,所以人們都不喜歡啰啰嗦嗦的表達(dá)方式。于是在相同認(rèn)知水平下,簡潔高效的表達(dá)是喜聞樂見的。本文將拋磚引玉,通過一些案例講解如何去簡化代碼。(轉(zhuǎn)載請指明出于breaksoftware的csdn博客)

關(guān)系數(shù)列

等差數(shù)列

? ? ? ? 比如我們要構(gòu)建的序列存儲的值是0,1,2,3,4……9999。

常規(guī)寫法

? ? ? ? 使用for循環(huán)

std::vector<int> vec;
for (int i = 0; i < 10000; i++) {vec.push_back(i);
}

簡潔寫法

iota

? ? ? ? 使用std標(biāo)準(zhǔn)庫的iota。

std::vector<int> vec(10);
std::iota(vec.begin(), vec.end(), 0);

generate

? ? ? ? 使用std標(biāo)準(zhǔn)庫的generate

    std::vector<int> vec(10);std::generate(vec.begin(), vec.end(), [] {static int i = 0; return i++;});

? ? ? ? 或者

    std::vector<int> vec(10);std::generate(vec.begin(), vec.end(), [n = 0]() mutable {return n++;});

partial_sum

? ? ? ? 使用std標(biāo)準(zhǔn)庫的partial_sum,代碼量減少了一半。?partial是局部、區(qū)間的意思,sum是累加的意思。第1、2個參數(shù)是需要被計算的容器起止迭代器,第3個參數(shù)是計算結(jié)果保存的起始迭代器。它還有第4個參數(shù),用于描述怎么計算的。

std::vector<int> vec(10000, 1);
vec[0] = 0;
std::partial_sum(vec.begin(), vec.end(), vec.begin());

? ? ? ? std::partial_sum方法對區(qū)間數(shù)據(jù)進(jìn)行累加。具體的計算規(guī)則是

template< class InputIt, class OutputIt >
OutputIt partial_sum( InputIt first, InputIt last, OutputIt d_first );
// *(d_first)   = *first;
// *(d_first+1) = *first + *(first+1);
// *(d_first+2) = *first + *(first+1) + *(first+2);
// *(d_first+3) = *first + *(first+1) + *(first+2) + *(first+3);
// ...

? ? ? ? 上述方法有個缺點,就是需要填充10000個1之后再計算。我們可以稍微修改如下,效率會好些。

std::vector<int> vec(10000);
vec[0] = 0;
std::partial_sum(vec.begin(), vec.end(), vec.begin(), [](const int&a, int b) {return a + 1;});

? ? ? ? 如果要生成9999,9998……0這樣遞減的數(shù)列,則可以把第一個元素賦值為9999后,傳遞一個減法lambda表達(dá)式

std::vector<int> vec(10000);
vec[0] = 9999;
std::partial_sum(vec.begin(), vec.end(), vec.begin(), [](const int& a, int b) {return a - 1;} );

等比數(shù)列

? ? ? ? 比如我們要生成1,2,4,8,16……這樣2倍關(guān)系的數(shù)列。

常規(guī)寫法

std::vector<int> vec;
for (int i = 0; i < 10; i++) {vec.push_back(pow(2, i));
}

精簡寫法

?generate

    std::vector<int> vec(10);std::generate(vec.begin(), vec.end(), [] {static int i = 0; return pow(2, i++);});

? ? ? ? 或者

    std::vector<int> vec(10);std::generate(vec.begin(), vec.end(), [n = 0]() mutable {return pow(2, n++);});

partial_sum

std::vector<int> vec(10, 2);
vec[0] = 1;
std::partial_sum(vec.begin(), vec.end(), vec.begin(), std::multiplies<int>());

? ? ? ? 使用比值2初始化vector容器,然后給partial_sum傳遞乘法函數(shù)對象。

? ? ? ? 或者使用lambda表達(dá)式

std::vector<int> vec(10);
vec[0] = 1;
std::partial_sum(vec.begin(), vec.end(), vec.begin(), [](const int& x, int y) {return x * 2;});

? ? ? ? 如果要生成512,256……2,1這樣的等比數(shù)列,則可以把容器的第一個元素設(shè)置為1024,然后給partial_sum傳遞除法函數(shù)對象。

std::vector<int> vec(10, 2);
vec[0] = 512;
std::partial_sum(vec.begin(), vec.end(), vec.begin(), std::divides<int>());

? ? ? ? 或者使用lambda表達(dá)式

std::vector<int> vec(10);
vec[0] = 512;
std::partial_sum(vec.begin(), vec.end(), vec.begin(), [](const int& x, int y) {return x / 2;});

斐波那契數(shù)列

常規(guī)寫法

std::vector<int> vec(10);
vec[0] = 1;
for (auto it = std::next(vec.begin()); it != vec.end(); it++) {auto it_prev = std::prev(it);if (vec.begin() != it_prev) {*it = *it_prev + *std::prev(it_prev);}else {*it = *it_prev;}  
}

精簡寫法

std::vector<int> vec(10);
vec[0] = 1;
std::adjacent_difference(vec.begin(), std::prev(vec.end()), std::next(vec.begin()), std::plus<int>());

? ? ? ??adjacent_difference用于計算前后兩個數(shù)據(jù)的差。第4個參數(shù)的默認(rèn)操作是減法,其計算規(guī)則如下

template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardIt2 adjacent_difference( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first );
// *(d_first)   = *first;
// *(d_first+1) = *(first+1) - *(first);
// *(d_first+2) = *(first+2) - *(first+1);
// *(d_first+3) = *(first+3) - *(first+2);
// ...

累計型操作

? ? ? ? 比較常見的累計型操作如累加、累乘

累加

常規(guī)寫法

std::vector<int> vec = { 16, 8, 4 };
int sum = 0;
for (int n : vec) {sum += n;
}

精簡寫法

std::vector<int> vec = { 16, 8, 4 };
int sum = std::accumulate(vec.begin(), vec.end(), 0);

? ? ? ? 代碼也減少一半。

? ? ? ??accumulate第1、2個參數(shù)是需要計算的容器的起止迭代器,第3個參數(shù)是初始計算的值。它還有第4個參數(shù),用于描述如何累計。默認(rèn)是累加操作。

? ? ? ? 我們再看個累乘操作。

std::vector<int> vec = { 16, 8, 4 };
int product = std::accumulate(vec.begin(), vec.end(), 1, std::multiplies<int>());

組合成一個字符串

常規(guī)寫法

std::vector<int> vec = { 16, 8, 4 };
std::string str;
for (int n : vec) {if (!str.empty()) {str.append(",");}str.append(std::to_string(n));
}

精簡寫法

std::string s = std::accumulate(std::next(vec.begin()), vec.end(),std::to_string(vec[0]), // start with first element[](std::string a, int b) { return a + ',' + std::to_string(b);}
);

序列比較

兩個序列中,相同偏移的元素值相等的個數(shù)

常規(guī)寫法

std::vector<int> a = { 1, 2, 3, 4, 5 };
std::vector<int> b = { 5, 4, 3, 2, 1 };
int num = 0;
auto it_a = a.begin();
auto it_b = b.begin();
for (; it_a != a.end() && it_b != b.end(); it_a++, it_b++) {if (*it_a == *it_b) {num++;}
}

精簡寫法

std::vector<int> a = { 1, 2, 3, 4, 5 };
std::vector<int> b = { 5, 4, 3, 2, 1 };
int num = std::inner_product(a.begin(), a.end(), b.begin(), 0, std::plus<>(), std::equal_to<>());

? ? ? ??inner_product方法對兩個序列中相同位置的元素使用第5個參數(shù)指向的函數(shù)對象計算,計算的結(jié)果通過第4個參數(shù)指向的函數(shù)對象進(jìn)行再計算。即

template<class InputIt1, class InputIt2, class T,class BinaryOperation1, class BinaryOperation2> 
T inner_product( InputIt1 first1, InputIt1 last1,InputIt2 first2, T init,BinaryOperation1 op1,BinaryOperation2 op2 );
// 以初值 init 初始化積累器 acc ,然后
// 以表達(dá)式 acc = op1(acc, op2(*first1, *first2)) 修改它,再以表達(dá)式acc = op1(acc, op2(*(first1+1), *(first2+1))) 修改它,以此類推

兩個序列元素是否完全一致(順序無關(guān))

? ? ? ? 比如一個序列a是1,2,3;序列b是2,1,3;序列c是1,2,1。則a和b中元素完全一致,只是順序不一致;而c和a、b中元素不一致。可以想象這個算法不是簡簡單單就能寫出來的。我們直接看精簡寫法

精簡寫法

std::vector<int> v1{ 1,1,2,2,5 };
std::vector<int> v2{ 5,1,2,1,2 };
bool permutation = std::is_permutation(v1.begin(), v1.end(), v2.begin(), v2.end());

? ? ? ??is_permutation用于判斷兩個序列是否是同一個序列的不同(或相同)順序排列。

總結(jié)

以上是生活随笔為你收集整理的C++拾取——使用stl标准库生成等差、等比数列的方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。