C++中STL常用算法


算法主要是由頭文件 組成。 是所有STL頭文件中最大的一個,其中常用的功能涉 及到比較,交換,查找,遍歷,複製,修改,反轉,排序,合併等…體積很小,只 包括在幾個序列容器上進行的簡單運算的模板函數. 定義了一些模板類,用以聲明 函數對象。

1、常用的遍歷算法

1、for_each:遍歷容器元素


遍 歷 算 法 遍 歷 容 器 元 素 
	@param beg 開 始 迭 代 器 
	@param end 結 束 迭 代 器 
	@param _callback 函 數 回 調 或 者 函 數 對 象 
	@return 函 數 對 象
for_each(iterator beg, iterator end, _callback); 

2、transform算法 將指定容器區間元素搬運到另一容器中

注意 : 
transform 不會給目標容器分配內存,所以需要我們提前分配好內存 
	@param beg1 源容器開始迭代器 
	@param end1 源容器結束迭代器 
	@param beg2 目標容器開始迭代器 
	@param _cakkback 回調函數或者函數對象 
	@return 返回目標容器迭代器
transform(iterator beg1, iterator end1, iterator beg2, _callbakc);

在這裏插入圖片描述

int myTransInt(int val)
{
    return val;
}
class MyTransInt{
public:
    int operator()(int val)
    {
        return val;
    }
};

void test02()
{
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);

    //將v1容器的元素 幫運到 v2中
    vector<int> v2;
    //預先:設置v2的大小(注意!!!)
    v2.resize(v1.size());

    //transform(v1.begin(),v1.end(),v2.begin(), 搬運方式);
    //transform(v1.begin(),v1.end(),v2.begin(),myTransInt);
    transform(v1.begin(),v1.end(),v2.begin(),MyTransInt());

    for_each(v2.begin(),v2.end(),[](int val){cout<<val<<" ";});
    cout<<endl;
}

運行結果:
在這裏插入圖片描述

2、常用的查找算法

2.1、find算法 查找元素

find算 法 查 找 元 素 
	@param beg 容 器 開 始 迭 代 器 
	@param end 容 器 結 束 迭 代 器 
	@param value 查 找 的 元 素 
	@return 返 回 查 找 元 素 的 位 置
find(iterator beg, iterator end, value) 

失敗返回v.end()

#include<string>
class Person
{
public:
    string name;
    int age;
public:
    Person(string name,int age)
    {
        this->name = name;
        this->age = age;
    }
    bool operator==(const Person &ob)
    {
        if(this->name == ob.name && this->age==ob.age)
            return true;
        return false;
    }
};
void test03()
{
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);

    vector<int>::iterator ret;
    ret = find(v1.begin(),v1.end(),20);
    if(ret != v1.end())
    {
        cout<<"找到的數據爲:"<<*ret<<endl;
    }

    vector<Person> v2;
    v2.push_back(Person("德瑪西亞",18));
    v2.push_back(Person("小法",19));
    v2.push_back(Person("小炮",20));
    v2.push_back(Person("牛頭",21));

    Person tmp("小炮",20);
    vector<Person>::iterator ret2;
    //對於find尋找自定義數據 需要重載==
    ret2 = find(v2.begin(),v2.end(),tmp);
    if(ret2 != v2.end())
    {
        cout<<"找到的數據name="<<(*ret2).name<<",age="<<(*ret2).age<<endl;
    }
}

運行結果:
在這裏插入圖片描述

2、find_if條件查找


find_if算 法 條 件 查 找 
	@param beg 容 器 開 始 迭 代 器 
	@param end 容 器 結 束 迭 代 器 
	@param callback 回 調 函 數 或 者 謂 詞 ( 返 回 bool類 型 的 函 數 對 象 )
	@return bool
	查 找 返 回 true
	否 則 false
find_if(iterator beg, iterator end, _callback);
bool myGreaterThan20(int val)
{
    return val>20;
}
class MyGreaterThan20{
public:
    bool operator()(int val)
    {
        return val>20;
    }
};

void test04()
{
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);

    //尋找第一個大於20的數
    vector<int>::iterator ret;
    //ret = find_if(v1.begin(),v1.end(), myGreaterThan20 );
    ret = find_if(v1.begin(),v1.end(), MyGreaterThan20() );
    if(ret != v1.end())
    {
        cout<<"尋找到的數據爲:"<<*ret<<endl;
    }
}

運行結果:
在這裏插入圖片描述

2.3、adjacent_find算法 查找相鄰重複元素

adjacent_find算 法 查 找 相 鄰 重 復 元 素
	@param beg容 器 開 始 迭 代 器
	@param end容 器 結 束 迭 代 器 
	@param _callback回調函數或者謂詞(返回bool類型的函數對象)
	@return返回相鄰元素的第一個位置的迭代器 
adjacent_find(iterator beg, iterator end, _callback);
void test05()
{
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(20);
    v1.push_back(40);
    v1.push_back(50);
    v1.push_back(50);
    vector<int>::iterator ret;
    //對於普通數據 不需要回調函數
    ret = adjacent_find(v1.begin(),v1.end());
    if(ret != v1.end())
    {
        cout<<"尋找到重複的數據:"<<*ret<<endl;
    }

    vector<Person> v2;
    v2.push_back(Person("德瑪西亞",18));
    v2.push_back(Person("小法",19));
    v2.push_back(Person("小法",19));
    v2.push_back(Person("牛頭",21));
    vector<Person>::iterator ret2;
    ret2 = adjacent_find(v2.begin(),v2.end());
    if(ret2 != v2.end())
    {
        cout<<"尋找到重複的數據:"<<(*ret2).name<<" "<<(*ret2).age<<endl;
    }
}

運行結果:
在這裏插入圖片描述

2.4、binary_search算法 二分查找法(容器必須有序)

binary_search算 法 二 分 查 找 法
	注 意 :
	在 無 序 序 列 中 不 可 用 
	@param beg 容 器 開 始 迭 代 器 
	@param end 容 器 結 束 迭 代 器 
	@param value 查 找 的 元 素 
	@return bool 查找到返回 true 否則 false
bool binary_search(iterator beg, iterator end, value); 
void test06()
{
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);

    bool ret = binary_search(v1.begin(),v1.end(),30);
    if(ret == true)
    {
        cout<<"找到"<<endl;//找到
    }
    else
    {
        cout<<"未找到"<<endl;
    }
}

2.5、count算法 統計元素出現次數

count算 法 統 計 元 素 出 現 次 數 
	@param beg 容 器 開 始 迭 代 器 
	@param end 容 器 結 束 迭 代 器 
	@param value 回 調 函 數 或 者 謂 詞 ( 返 回 bool類 型 的 函 數 對 象 )
	@return int 返 回 元 素 個 數
count(iterator beg, iterator end, value); 
void test07()
{
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(10);
    v1.push_back(40);
    v1.push_back(10);

    cout<<count(v1.begin(),v1.end(),10)<<endl;//3
}

2.6、count_if算法 統計元素出現次數

count_if算 法 統 計 元 素 出 現 次 數 
	@param beg 容 器 開 始 迭 代 器 
	@param end 容 器 結 束 迭 代 器 
	@param callback 回 調 函 數 或 者 謂 詞 ( 返 回 bool類 型 的 函 數 對 象 )
	@return int返 回 元 素 個 數
count_if(iterator beg, iterator end, _callback); 
bool myGreaterThan10(int val)
{
    return val>10;
}
class MyGreaterThan10
{
public:
    bool operator()(int val)
    {
        return val>10;
    }
};
void test07()
{
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(10);
    v1.push_back(40);
    v1.push_back(10);

    cout<<count(v1.begin(),v1.end(),10)<<endl;//3

    //普通函數
    cout<<count_if(v1.begin(),v1.end(), myGreaterThan10)<<endl;//2
    //函數對象
    cout<<count_if(v1.begin(),v1.end(), MyGreaterThan10())<<endl;//2
    //內建函數對象
    cout<<count_if(v1.begin(),v1.end(), bind2nd(greater<int>(),10))<<endl;//2
}

運行結果:
在這裏插入圖片描述

3、常用排序算法

3.1、merge算法 容器元素合併,並存儲到另一容器中(每個容器必須有序)

merge算 法 容 器 元 素 合 並 , 並 存 儲 到 另 一 容 器 中
	注 意 : 兩 個 容 器 必 須 是 有 序 的 
	@param beg1 容 器 1 開 始 迭 代 器 
	@param end1 容 器 1 結 束 迭 代 器 
	@param beg2 容 器 2 開 始 迭 代 器 
	@param end2 容 器 2 結 束 迭 代 器 
	@param dest 目 標 容 器 開 始 迭 代 器
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterat or dest)
void test01()
{
    vector<int> v1;
    v1.push_back(1);
    v1.push_back(3);
    v1.push_back(5);
    v1.push_back(7);

    vector<int> v2;
    v2.push_back(2);
    v2.push_back(4);
    v2.push_back(6);
    v2.push_back(8);

    vector<int> v3;
    //預先:設置v3的大小
    v3.resize(v1.size()+v2.size());

    merge(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());

    for_each(v3.begin(),v3.end(),[](int val){cout<<val<<" ";});
    cout<<endl;
}

運行結果:
在這裏插入圖片描述

3.2、sort算法 容器元素排序

sort算 法 容 器 元 素 排 序 
	@param beg 容 器 1 開 始 迭 代 器 
	@param end 容 器 1 結 束 迭 代 器 
	@param _callback 回 調 函 數 或 者 謂 詞 ( 返 回 bool類 型 的 函 數 對 象 )
sort(iterator beg, iterator end, _callback) 

3.3、random_shuffle算法 對指定範圍內的元素隨機調整次序

random_shuffle算 法 對 指 定 範 圍 內 的 元 素 隨 機 調 整 次 序
	@param beg容 器 開 始 迭 代 器
	@param end容 器 結 束 迭 代 器
random_shuffle(iterator beg, iterator end) 
#include<time.h>
void test02()
{
    vector<int> v1;
    v1.push_back(1);
    v1.push_back(3);
    v1.push_back(5);
    v1.push_back(7);

    //srand設置種子
    srand(time(NULL));

    for_each(v1.begin(),v1.end(),[](int val){cout<<val<<" ";});
    cout<<endl;

    //需要配置 srand
    random_shuffle(v1.begin(),v1.end());

    for_each(v1.begin(),v1.end(),[](int val){cout<<val<<" ";});
    cout<<endl;
}

運行結果:
在這裏插入圖片描述

3.4、reverse算法 反轉指定範圍的元素

reverse算 法 反 轉 指 定 範 圍 的 元 素 
	@param beg 容 器 開 始 迭 代 器 
	@param end 容 器 結 束 迭 代 器
reverse(iterator beg, iterator end)
void test03()
{
    vector<int> v1;
    v1.push_back(1);
    v1.push_back(3);
    v1.push_back(5);
    v1.push_back(7);
    for_each(v1.begin(),v1.end(),[](int val){cout<<val<<" ";});
    cout<<endl;//1 3 5 7

    reverse(v1.begin(),v1.end());

    for_each(v1.begin(),v1.end(),[](int val){cout<<val<<" ";});
    cout<<endl;//7 5 3 1
}

4、常用拷貝和替換算法

4.1、copy算法 將容器內指定範圍的元素拷貝到另一容器中

copy算 法 將 容 器 內 指 定 範 圍 的 元 素 拷 貝 到 另 一 容 器 中 
	@param beg 容 器 開 始 迭 代 器 
	@param end 容 器 結 束 迭 代 器 
	@param dest 目 標 起 始 迭 代 器
copy(iterator beg, iterator end, iterator dest) 
#include<iterator>
void test04()
{
    vector<int> v1;
    v1.push_back(1);
    v1.push_back(3);
    v1.push_back(5);
    v1.push_back(7);

    vector<int> v2;
    //預先:設置大小
    v2.resize(v1.size());

    copy(v1.begin(),v1.end(),v2.begin());

    for_each(v2.begin(),v2.end(),[](int val){cout<<val<<" ";});
    cout<<endl;//1 3 5 7

    //copy秀一下:用copy輸出(瞭解)
    copy(v2.begin(),v2.end(), ostream_iterator<int>(cout," ") );
}

運行結果:
在這裏插入圖片描述

4.2、replace算法 將容器內指定範圍的舊元素修改爲新元素

replace算 法 將 容 器 內 指 定 範 圍 的 舊 元 素 修 改 爲 新 元 素 
	@param beg 容 器 開 始 迭 代 器 
	@param end 容 器 結 束 迭 代 器 
	@param oldvalue 舊 元 素 
	@param oldvalue 新 元 素
replace(iterator beg, iterator end, oldvalue, newvalue) 

4.3、replace_if算法 將容器內指定範圍滿足條件的元素替換爲新元素

replace_if算 法 將 容 器 內 指 定 範 圍 滿 足 條 件 的 元 素 替 換 爲 新 元 素
	@param beg容 器 開 始 迭 代 器
	@param end容 器 結 束 迭 代 器 
	@param callback 函 數 回 調 或 者 謂 詞 ( 返 回 Bool類 型 的 函 數 對 象 )
	@param oldvalue新 元 素
replace_if(iterator beg, iterator end, _callback, newvalue)
void test05()
{
    vector<int> v1;
    v1.push_back(1);
    v1.push_back(3);
    v1.push_back(5);
    v1.push_back(7);

    //將容器中的3替換成3000
    replace(v1.begin(),v1.end(),3,3000);
    copy(v1.begin(),v1.end(), ostream_iterator<int>(cout," ") );
    cout<<endl;

    vector<int> v2;
    v2.push_back(1);
    v2.push_back(3);
    v2.push_back(5);
    v2.push_back(7);
    //將容器的大於3替換成3000
    replace_if(v2.begin(),v2.end(),  bind2nd(greater<int>(),3) , 1000 );
    copy(v2.begin(),v2.end(), ostream_iterator<int>(cout," ") );
    cout<<endl;
}

運行結果:
在這裏插入圖片描述

4.4、swap算法 互換兩個容器的元素

swap算 法 互 換 兩 個 容 器 的 元 素 
	@param c1 容 器 1 
	@param c2 容 器 2
swap(container c1, container c2) 

5、算術生成算法

5.1、accumulate算法 計算容器元素累計總和

accumulate算 法 計 算 容 器 元 素 累 計 總 和
	@param beg容 器 開 始 迭 代 器
	@param end容 器 結 束 迭 代 器 
	@param value 累 加 值
accumulate(iterator beg, iterator end, value) 
void test06()
{
    vector<int> v1;
    v1.push_back(1);
    v1.push_back(3);
    v1.push_back(5);
    v1.push_back(7);

    int sum = accumulate(v1.begin(),v1.end(),1000);
    cout<<"sum = "<<sum<<endl;//1016
}

5.2、fill算法 向容器中添加元素

fill算 法 向 容 器 中 添 加 元 素 
	@param beg 容 器 開 始 迭 代 器 
	@param end 容 器 結 束 迭 代 器 
	@param value t 填 充 元 素
fill(iterator beg, iterator end, value)

#include<iterator>
#include<vector>
#include<algorithm>
void test07()
{
    vector<int> v;
    v.resize(5);
    fill(v.begin(),v.end(),50);
    for_each(v.begin(),v.end(),[](int vel){cout<<vel<<" ";});
    cout<<endl;
}

6、常用集合算法

在這裏插入圖片描述
在這裏插入圖片描述

6.1、set_intersection算法 求兩個set集合的交集

set_intersection算法 求兩個set集合的交集
	注意:兩個集合必須是有序序列
	@param beg1 容器1開始迭代器
	@param end1 容器1結束迭代器
	@param beg2 容器2開始迭代器
	@param end2 容器2結束迭代器
	@param dest  目標容器開始迭代器
	@return 目標容器的最後一個元素的迭代器地址
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)

6.2、set_intersection算法 求兩個set集合的交集

set_union算法 求兩個set集合的並集
	注意:兩個集合必須是有序序列
	@param beg1 容器1開始迭代器
	@param end1 容器1結束迭代器
	@param beg2 容器2開始迭代器
	@param end2 容器2結束迭代器
	@param dest  目標容器開始迭代器
	@return 目標容器的最後一個元素的迭代器地址
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)

6.3、set_difference算法 求兩個set集合的差集

set_difference算法 求兩個set集合的差集
	注意:兩個集合必須是有序序列
	@param beg1 容器1開始迭代器
	@param end1 容器1結束迭代器
	@param beg2 容器2開始迭代器
	@param end2 容器2結束迭代器
	@param dest  目標容器開始迭代器
	@return 目標容器的最後一個元素的迭代器地址
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
void test08()
{
    vector<int> A;
    A.push_back(1);
    A.push_back(3);
    A.push_back(5);
    A.push_back(7);
    A.push_back(9);

    vector<int> B;
    B.push_back(7);
    B.push_back(9);
    B.push_back(2);
    B.push_back(4);
    B.push_back(6);

    //求交集
    vector<int> v1;//存放交集
    v1.resize(min(A.size(),B.size()));

    vector<int>::iterator myEnd= set_intersection(A.begin(),A.end(),B.begin(),B.end(), v1.begin());
    copy(v1.begin(), myEnd, ostream_iterator<int>(cout," ") );
    cout<<endl;

    //求並集
    vector<int> v2;//存放並集
    v2.resize(A.size()+B.size() );
    myEnd = set_union(A.begin(),A.end(),B.begin(),B.end(), v2.begin());
    copy(v2.begin(), myEnd, ostream_iterator<int>(cout," ") );
    cout<<endl;

    //求差集 A 差 B
    vector<int> v3;//存放並集
    v3.resize( A.size() );
    myEnd = set_difference(A.begin(),A.end(),B.begin(),B.end(), v3.begin());
    copy(v3.begin(), myEnd, ostream_iterator<int>(cout," ") );
    cout<<endl;
}

運行結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章