成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

后悔沒早點知道!這 18 個 STL 算法讓代碼效率暴增 200%

開發
本文介紹的這18個STL算法就像武功秘籍一樣,每一個都能讓你的代碼變得更短、更快、更優雅。關鍵是它們都經過了高度優化,性能比你手寫的循環要好得多。

哥們,說實話,你是不是還在用那種寫了10行代碼才能搞定的事情?比如找個最大值要寫個for循環,判斷個條件要if套if?

我之前也是這樣,直到我發現了STL里藏著的這些"黑科技"。用了之后,代碼不僅變短了,運行速度還提升了幾倍!同事們都問我是不是偷偷上了什么培訓班。

今天就把這些壓箱底的寶貝分享給你,保證你看完之后會拍大腿說:"臥槽,還有這種操作!"

1. std::iota - 數列生成器,告別手寫循環

以前的你:

vector<int> nums(10);
for(int i = 0; i < 10; i++) {
    nums[i] = i + 1;
}

現在的你:

#include <numeric>
vector<int> nums(10);
std::iota(nums.begin(), nums.end(), 1);
// 輸出:1 2 3 4 5 6 7 8 9 10

看到沒?一行代碼搞定!iota這個名字來自希臘字母,專門用來生成連續數列。想生成1到100?想生成-5到5?隨你折騰!

vector<int> countdown(5);
std::iota(countdown.begin(), countdown.end(), -2);
// 輸出:-2 -1 0 1 2

2. std::adjacent_find - 找重復鄰居的神器

你有沒有遇到過這種情況:要找數組里第一個重復的相鄰元素?比如找字符串里的連續重復字符?

笨辦法:

string s = "programming";
int pos = -1;
for(int i = 0; i < s.length() - 1; i++) {
    if(s[i] == s[i+1]) {
        pos = i;
        break;
    }
}

聰明做法:

#include <algorithm>  // 這個是關鍵!adjacent_find在這里
#include <string>     

string s = "programming";
auto it = std::adjacent_find(s.begin(), s.end());
if(it != s.end()) {
    cout << "找到重復字符: " << *it << " 位置: " << it - s.begin() << endl;
}
// 輸出:找到重復字符: m 位置: 6

這個函數還能自定義比較條件!比如找第一對差值大于10的相鄰數字:

vector<int> nums = {1, 3, 5, 18, 20};
auto it = std::adjacent_find(nums.begin(), nums.end(), 
    [](int a, int b) { return abs(a - b) > 10; });
// 找到5和18這對冤家

3. std::inner_product - 向量運算的瑞士軍刀

這個函數名字聽起來很數學,但其實超級實用!不僅能計算點積,還能做各種神奇的運算。

計算兩個數組的點積:

#include <numeric>  

vector<int> a = {1, 2, 3};
vector<int> b = {4, 5, 6};
int result = std::inner_product(a.begin(), a.end(), b.begin(), 0);
cout << result << endl;  // 輸出:32 (1*4 + 2*5 + 3*6)

更騷的操作 - 自定義運算:

// 計算兩個數組對應位置的差值之和
vector<int> prices_yesterday = {100, 200, 150};
vector<int> prices_today = {105, 195, 160};
int total_change = std::inner_product(
    prices_today.begin(), prices_today.end(), 
    prices_yesterday.begin(), 0,
    std::plus<>(),  // 累加
    std::minus<>()  // 相減
);
cout << "總體價格變化: " << total_change << endl;  // 輸出:10

4. std::nth_element - 找第N大元素的速度怪獸

要找第K大的元素,你是不是還在排序然后取下標?兄弟,這樣太慢了!

傳統做法(慢):

vector<int> nums = {3, 1, 4, 1, 5, 9, 2, 6};
sort(nums.begin(), nums.end());
cout << nums[2] << endl;  // 第3小的元素

高效做法:

#include <algorithm>

vector<int> nums = {3, 1, 4, 1, 5, 9, 2, 6};
std::nth_element(nums.begin(), nums.begin() + 2, nums.end());
cout << nums[2] << endl;  // 輸出:2
// 而且nums[2]左邊的都比它小,右邊的都比它大!

這個函數的時間復雜度是O(n),比排序的O(nlogn)快多了!找中位數、找前K大元素都是它的拿手好戲。

5. std::partial_sum - 前綴和計算機

算前綴和還在手寫雙重循環?這個函數一步到位!

#include <numeric>  // partial_sum在這里

vector<int> nums = {1, 2, 3, 4, 5};
vector<int> prefix_sum(nums.size());
std::partial_sum(nums.begin(), nums.end(), prefix_sum.begin());
// prefix_sum: [1, 3, 6, 10, 15]

for(int x : prefix_sum) {
    cout << x << " ";
}

還能玩出花來:

vector<int> nums = {2, 3, 4, 5};
vector<int> products(nums.size());
std::partial_sum(nums.begin(), nums.end(), products.begin(), 
                 std::multiplies<int>());
// products: [2, 6, 24, 120] (累乘)

6. std::rotate - 數組旋轉大師

左旋轉、右旋轉,一個函數全搞定!

#include <algorithm>  // std::rotate在這里

vector<int> nums = {1, 2, 3, 4, 5, 6, 7};
// 向左旋轉3位
std::rotate(nums.begin(), nums.begin() + 3, nums.end());
// 結果:[4, 5, 6, 7, 1, 2, 3]

for(int x : nums) {
    cout << x << " ";
}

字符串操作也超級方便:

string s = "abcdefg";
std::rotate(s.begin(), s.begin() + 2, s.end());
cout << s << endl;  // 輸出:cdefgab

7. std::set_intersection - 求交集的專家

兩個有序數組求交集,不用自己寫雙指針了!

#include <algorithm>  // std::set_intersection在這里

vector<int> a = {1, 2, 3, 4, 5};
vector<int> b = {3, 4, 5, 6, 7};
vector<int> result;

std::set_intersection(a.begin(), a.end(), b.begin(), b.end(),
                     std::back_inserter(result));
// result: [3, 4, 5]

cout << "交集: ";
for(int x : result) {
    cout << x << " ";
}

還有set_union(并集)、set_difference(差集)等兄弟函數,處理集合運算簡直不要太爽!

8. std::lexicographical_compare - 字典序比較王者

真正的字典序比較,就像查字典一樣!比較兩個序列誰在"字典"里排在前面:

#include <algorithm>  // std::lexicographical_compare在這里

vector<string> words1 = {"apple", "banana"};
vector<string> words2 = {"apple", "cherry"};

bool result = std::lexicographical_compare(
words1.begin(), words1.end(),
words2.begin(), words2.end()
);

cout << (result ? "words1 在字典中排在前面" : "words2 在字典中排在前面") << endl;
// 輸出:words1 在字典中排在前面 (因為 banana < cherry)

字符串比較也很直觀:

string s1 = "abc";
string s2 = "abd";

bool result = std::lexicographical_compare(s1.begin(), s1.end(), 
s2.begin(), s2.end());
cout << (result ? "s1 < s2" : "s1 >= s2") << endl;  // 輸出:s1 < s2

自定義比較規則,比如忽略大小寫:

string s1 = "Apple";
string s2 = "banana";

bool result = std::lexicographical_compare(
s1.begin(), s1.end(), s2.begin(), s2.end(),
[](char a, char b) { 
    return tolower(a) < tolower(b); 
}
);
// 按忽略大小寫的字典序比較

9. std::inplace_merge - 原地歸并排序

有兩個已排序的數組段,想合并成一個?這個函數就是為你準備的!

#include <algorithm>  // std::inplace_merge在這里

vector<int> nums = {1, 3, 5, 2, 4, 6};
// 前半部分[1,3,5]已排序,后半部分[2,4,6]已排序
std::inplace_merge(nums.begin(), nums.begin() + 3, nums.end());
// 結果:[1, 2, 3, 4, 5, 6]

for(int x : nums) {
    cout << x << " ";
}

內存效率超高,時間復雜度O(n),歸并排序的核心就是它!

10. std::sample - 隨機采樣專家

從大數據集里隨機選幾個樣本?這個函數幫你搞定!

#include <random>
#include <algorithm>  // std::sample在這里

vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
vector<int> samples;

std::random_device rd;
std::mt19937 gen(rd());

std::sample(data.begin(), data.end(), std::back_inserter(samples), 
           3, gen);  // 隨機選3個

cout << "隨機樣本: ";
for(int x : samples) {
    cout << x << " ";
}
// 可能輸出:隨機樣本: 2 7 9

做數據分析、機器學習預處理的時候超級有用!

11. std::partition - 數據分類專家

想把數組按條件分成兩部分?比如把奇數放前面,偶數放后面?

#include <algorithm>  // std::partition在這里

vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9};
auto it = std::partition(nums.begin(), nums.end(), 
                        [](int x) { return x % 2 == 1; });

cout << "奇數部分: ";
for(auto i = nums.begin(); i != it; ++i) {
    cout << *i << " ";  // 輸出:1 9 3 7 5
}
cout << "\n偶數部分: ";
for(auto i = it; i != nums.end(); ++i) {
    cout << *i << " ";  // 輸出:6 4 8 2
}

還有個更穩定的版本std::stable_partition,能保持原有的相對順序!

12. std::mismatch - 找不同點的偵探

比較兩個序列,找出第一個不同的位置:

#include <algorithm>  // std::mismatch在這里

string s1 = "programming";
string s2 = "programing";  // 少了一個m

auto result = std::mismatch(s1.begin(), s1.end(), s2.begin());
if(result.first != s1.end()) {
    cout << "第一個不同的位置: " << (result.first - s1.begin()) << endl;
    cout << "字符分別是: '" << *result.first << "' 和 '" << *result.second << "'" << endl;
}
// 輸出:第一個不同的位置: 7
//      字符分別是: 'm' 和 'i'

做字符串diff、數據校驗的時候特別有用!

13. std::equal_range - 二分查找三件套

在有序數組里查找某個值的所有出現位置,一次性給你上下邊界:

#include <algorithm>  // std::equal_range在這里

vector<int> nums = {1, 2, 2, 2, 3, 4, 5};
auto range = std::equal_range(nums.begin(), nums.end(), 2);

cout << "數字2的范圍: [" << (range.first - nums.begin()) 
     << ", " << (range.second - nums.begin()) << ")" << endl;
// 輸出:數字2的范圍: [1, 4)

cout << "數字2出現了 " << (range.second - range.first) << " 次" << endl;
// 輸出:數字2出現了 3 次

比lower_bound和upper_bound分別調用要高效!

14. std::clamp - 數值限制器

把數值限制在某個范圍內,超出就截斷:

#include <algorithm>

int score = 150;
int clamped = std::clamp(score, 0, 100);  // 限制在0-100之間
cout << "原始分數: " << score << ", 限制后: " << clamped << endl;
// 輸出:原始分數: 150, 限制后: 100

double temperature = -10.5;
double safe_temp = std::clamp(temperature, -5.0, 35.0);
cout << "溫度調節: " << temperature << " -> " << safe_temp << endl;
// 輸出:溫度調節: -10.5 -> -5

游戲開發、數據處理時經常用到!

15. std::generate_n - 批量生成器

想生成N個隨機數?想批量初始化數據?這個函數幫你搞定:

#include <random>
#include <algorithm>

vector<int> random_nums(10);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 100);

std::generate_n(random_nums.begin(), 10, [&]() { return dis(gen); });

cout << "10個隨機數: ";
for(int x : random_nums) {
    cout << x << " ";
}

還能生成其他類型的數據:

vector<string> passwords(5);
std::generate_n(passwords.begin(), 5, []() {
    return "pwd_" + to_string(rand() % 1000);
});
// 生成5個隨機密碼

16. std::search_n - 連續元素搜索專家

找連續出現N次的元素?比如找股票連續3天漲停,或者找字符串里連續的空格?

#include <algorithm>  // std::search_n在這里

vector<int> stock_changes = {1, -1, 1, 1, 1, -1, 1, 1};  // 1表示漲,-1表示跌
auto it = std::search_n(stock_changes.begin(), stock_changes.end(), 3, 1);

if(it != stock_changes.end()) {
    cout << "找到連續3天上漲,開始位置: " << (it - stock_changes.begin()) << endl;
    // 輸出:找到連續3天上漲,開始位置: 2
}

// 字符串中找連續空格
string text = "hello    world";  // 4個連續空格
auto pos = std::search_n(text.begin(), text.end(), 3, ' ');
if(pos != text.end()) {
    cout << "找到3個連續空格,位置: " << (pos - text.begin()) << endl;
}

還能自定義條件:

vector<int> temps = {25, 26, 27, 28, 29, 20, 15};  // 溫度數據
// 找連續3天溫度都超過25度
auto it = std::search_n(temps.begin(), temps.end(), 3, 25, 
                       [](int actual, int threshold) { return actual > threshold; });

if(it != temps.end()) {
    cout << "找到連續3天超過25度,開始位置: " << (it - temps.begin()) << endl;
    // 輸出:找到連續3天超過25度,開始位置: 0 (25,26,27都>25)
}

17. std::partial_sort - 部分排序高手

只想要前K個最大/最小值?不用全排序!這個函數比sort快多了:

#include <algorithm>

vector<int> scores = {85, 92, 78, 96, 88, 73, 91, 89, 94, 77};
// 只要前3名,不用全部排序
std::partial_sort(scores.begin(), scores.begin() + 3, scores.end(), std::greater<int>());

cout << "前3名分數: ";
for(int i = 0; i < 3; i++) {
    cout << scores[i] << " ";  
}
// 輸出:前3名分數: 96 94 92

// 后面的元素順序是未定義的,但前3個一定是最大的3個!

找中位數也超級高效:

vector<double> data = {3.2, 1.5, 4.8, 2.1, 5.7, 1.2, 6.3, 2.9};
int mid = data.size() / 2;
std::partial_sort(data.begin(), data.begin() + mid + 1, data.end());
cout << "中位數: " << data[mid] << endl;

性能對比:

  • sort全排序:O(n log n)
  • partial_sort前K個:O(n log k) - 當k很小時,快很多!

18. std::unique_copy - 去重復制專家

想去重但不想修改原數組?這個函數幫你復制一份去重后的數據:

#include <algorithm>

vector<int> nums = {1, 1, 2, 2, 2, 3, 3, 4, 5, 5};
vector<int> unique_nums;

// 前提:原數組要先排序!
std::unique_copy(nums.begin(), nums.end(), std::back_inserter(unique_nums));

cout << "原數組: ";
for(int x : nums) cout << x << " ";
cout << "\n去重后: ";
for(int x : unique_nums) cout << x << " ";
// 輸出:去重后: 1 2 3 4 5

處理字符串也很方便:

string text = "aabbccddee";
string result;
std::unique_copy(text.begin(), text.end(), std::back_inserter(result));
cout << "去重字符串: " << result << endl;  // 輸出:abcde

高級用法 - 自定義去重條件:

vector<string> words = {"hello", "HELLO", "world", "WORLD", "test"};
vector<string> unique_words;

// 按忽略大小寫去重
std::sort(words.begin(), words.end(), [](conststring& a, conststring& b) {
    string lower_a = a, lower_b = b;
    transform(lower_a.begin(), lower_a.end(), lower_a.begin(), ::tolower);
    transform(lower_b.begin(), lower_b.end(), lower_b.begin(), ::tolower);
    return lower_a < lower_b;
});
for(string x : words) cout << x << " ";

std::unique_copy(words.begin(), words.end(), std::back_inserter(unique_words),
                [](conststring& a, conststring& b) {
                    string lower_a = a, lower_b = b;
                    transform(lower_a.begin(), lower_a.end(), lower_a.begin(), ::tolower);
                    transform(lower_b.begin(), lower_b.end(), lower_b.begin(), ::tolower);
                    return lower_a == lower_b;
                });
for(string x : unique_words) cout << x << " ";
// 結果:保留一個hello和一個world

使用技巧:

  • unique_copy要求輸入已排序
  • 用back_inserter可以自動擴容目標容器
  • 可以配合自定義比較函數做復雜去重

獎勵關:幾個超級實用的組合技

技巧1:快速去重并保持順序

vector<int> nums = {3, 1, 4, 1, 5, 9, 2, 6, 5};
// 方法:先排序,再unique
sort(nums.begin(), nums.end());
nums.erase(std::unique(nums.begin(), nums.end()), nums.end());
// 結果:[1, 2, 3, 4, 5, 6, 9]

技巧2:統計滿足條件的元素個數

vector<int> scores = {85, 92, 78, 96, 88, 73, 91};
int high_scores = std::count_if(scores.begin(), scores.end(), 
                               [](int x) { return x >= 90; });
cout << "高分人數: " << high_scores << endl;  // 輸出:3

技巧3:檢查是否全部/任意元素滿足條件

vector<int> ages = {18, 19, 20, 21, 22};

bool all_adult = std::all_of(ages.begin(), ages.end(), 
                            [](int x) { return x >= 18; });
cout << "都是成年人: " << (all_adult ? "是" : "否") << endl;

bool has_senior = std::any_of(ages.begin(), ages.end(), 
                             [](int x) { return x >= 65; });
cout << "有老年人: " << (has_senior ? "是" : "否") << endl;

總結:從此告別"笨代碼"

這18個STL算法就像武功秘籍一樣,每一個都能讓你的代碼變得更短、更快、更優雅。關鍵是它們都經過了高度優化,性能比你手寫的循環要好得多。

記住幾個使用技巧:

  • 頭文件要記牢 - <algorithm>、<numeric>、<iterator>是三大寶庫
  • 善用lambda表達式 - 自定義比較條件超級靈活,比寫函數對象簡單多了
  • 迭代器是萬金油 - 不只是vector,string、deque、list、set都能用
  • 性能優先選擇 - nth_element比排序快,partial_sort比全排序快,根據需求選最合適的
  • 組合使用威力大 - 比如sort + unique去重,partition + sort分類排序
  • 前置條件要注意 - 很多算法要求輸入已排序(如unique、binary_search)
  • 善用插入迭代器 - back_inserter、front_inserter讓容器自動擴容
  • 自定義比較函數 - 大部分算法都支持傳入比較函數,讓功能更強大

下次寫代碼之前,先問問自己:"有沒有STL算法能幫我?"說不定就能找到現成的輪子,何必自己造呢?

最后送你一句話:好的程序員不是寫代碼最多的,而是寫代碼最少的。用好STL,讓你的代碼簡潔如詩!

責任編輯:趙寧寧 來源: 跟著小康學編程
相關推薦

2020-01-09 12:11:02

Python 開發編程語言

2024-06-03 00:00:00

Tailwind工具CSS

2021-09-06 10:05:42

Chrome瀏覽器

2024-06-13 13:15:51

Go代碼

2024-06-18 12:51:53

Go開發

2024-07-22 00:00:00

2020-12-04 10:45:18

辦公軟件插件工具

2018-01-25 09:12:43

程序員技能bug

2025-05-06 03:01:00

GC參數調優

2016-10-09 20:07:43

2025-03-20 14:18:57

AI算法模型

2021-07-07 05:03:35

Debugger技巧Nodejs

2020-04-20 17:43:28

Java代碼優化開發

2024-12-12 12:00:00

代碼C++

2025-02-19 16:00:00

ES代碼ECMAScript

2021-12-25 22:29:31

類型編程Javascript類型體操

2025-02-28 14:00:00

結構體C#.NET 9

2017-04-18 10:36:17

FireFox工具前端開發

2025-01-10 08:38:16

2021-06-25 10:20:07

Linux技巧命令
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产成人99久久亚洲综合精品 | 日韩高清一区二区 | 久久综合国产 | 精品视频在线免费观看 | 欧美性网 | 韩日有码 | 久久高清| 四虎影音 | 91资源在线观看 | 亚洲在线 | 久草在线 | 精品欧美一区二区三区久久久 | 视频一区二区三区四区五区 | 精品免费在线 | 精品久久久久久久久久久 | 精品一区国产 | 一级黄色片毛片 | 亚洲一区中文 | 天天操夜夜操 | 日韩欧美手机在线 | 亚洲成人av在线播放 | 嫩草视频入口 | 久久久综合网 | 欧美性受xxxx白人性爽 | 国产精品 亚洲一区 | 日韩三区 | 久久www免费人成看片高清 | 三级黄片毛片 | 日本视频在线播放 | 欧美美女爱爱 | 欧洲毛片| 国产成人精品一区二区 | 在线免费国产 | 久久久精品视频免费看 | 国产91久久精品一区二区 | 黄频免费 | 国产精品视频免费观看 | 亚洲午夜精品久久久久久app | 毛片一区二区三区 | 毛片免费视频 | 国产精品欧美一区二区三区 |