STL 常用算法

1.      STL 常用算法

for_each()

1

//普通函数

voidFuncShowElemt2(int &t)

{

cout << t << " ";

}

 

    vector<int> v1;

    v1.push_back(1);

    v1.push_back(3);

    v1.push_back(5);

 

//通过回调函数  谁使用for_each 谁去填写回调函数的入口地址

for_each(v1.begin(), v1.end(), FuncShowElemt2);

 

2

typedef struct_Mystruct

{

    inta;

    intb;

}Mystruct;

 

void CallMyMethod(std::pair<const int,Mystruct>& pair)

{

    cout<<pair.first<<endl;

    cout<<pair.second.a<<endl;

    cout<<pair.second.b<<endl;

}

int main()

{

    map<int,Mystruct>mapTest;

    for_each(Map.begin(), Map.end(),CallMyMethod);

    return0;

}

find_if

1

bool IsOdd (int i) {

  return((i%2)==1);

}

 

int main () {

 std::vector<int> myvector;

 

 myvector.push_back(10);

 myvector.push_back(25);

 myvector.push_back(40);

 myvector.push_back(55);

 

 std::vector<int>::iterator it = std::find_if (myvector.begin(),myvector.end(), IsOdd);

  std::cout<< "The first odd value is " << *it << '\n';

  return 0;

}

 

2

#include <string>

#include <algorithm>

class map_value_finder

{

public:

      map_value_finder(const std::string&cmp_string):m_s_cmp_string(cmp_string){}

       booloperator ()(const std::map<int, std::string>::value_type &pair)

       {

            returnpair.second == m_s_cmp_string;

       }

private:

        conststd::string &m_s_cmp_string;                   

};

int main()

{

   std::map<int, std::string> my_map;

   my_map.insert(std::make_pair(10, "china"));

   my_map.insert(std::make_pair(20, "usa"));

   my_map.insert(std::make_pair(30, "english"));

    my_map.insert(std::make_pair(40,"hongkong"));   

   

   std::map<int, std::string>::iterator it = my_map.end();

    it =std::find_if(my_map.begin(), my_map.end(),map_value_finder("English"));

    if (it ==my_map.end())

      printf("not found\n");       

    else

      printf("found key:%d value:%s\n", it->first,it->second.c_str());

      

    return 0;       

}

sort

1.

bool Compare(const int &a, const int &b)

{

    returna < b; //从小到大

}

 

//普通函数

void printElement(int &t)

{

    cout << t << " ";

}

 

void testSort()

{

    vector<int> v1(10);

 

    for(int i=0; i<10; i++)

    {

        inttmp = rand() %100;

        v1[i] = tmp;

    }

 

    for(vector<int>::iterator it=v1.begin();it!=v1.end(); it++ )

    {

        cout << *it <<" ";

    }

    cout << endl;

    for_each(v1.begin(), v1.end(), printElement);

    cout << endl;

 

    sort(v1.begin(), v1.end(),Compare);

    for_each(v1.begin(), v1.end(),printElement);

    cout << endl;

}

2

1.      map中的keyvalue分别存放在一个pair类型的vector中,然后利用vectorsort函数排序,其中map_verb存放我的map

2.       再新建一个map结构,然后把已知的map值得keyvalue分别作为新mapvaluekey,这样map结构就会自动按照value值排序啦~~

Transform

1

//二元函数对象

template <typename T>

class SumAdd

{

public:

    T operator()(Tt1, T t2)

    {

        return t1 +t2;

    }

};

    //v1 v2 ==>v3

    vector<int>v1, v2;

    vector<int>v3;

    v1.push_back(1);

    v1.push_back(3);

    v1.push_back(5);

 

    v2.push_back(2);

    v2.push_back(4);

    v2.push_back(6);

 

    v3.resize(10);

transform(v1.begin(), v1.end(), v2.begin(), v3.begin(),SumAdd<int>() );

 

    for(vector<int>::iterator it=v3.begin(); it!=v3.end(); it++ )

    {

        cout<< *it << " ";

    }

    cout <<endl;

 

2

 

Find

1

int main () {

  // usingstd::find with array and pointer:

  int myints[] = {10, 20, 30, 40 };

  int * p;

 

  p = std::find(myints, myints+4, 30);

  if (p !=myints+4)

    std::cout<< "Element found in myints: " << *p << '\n';

  else

    std::cout<< "Element not found in myints\n";

 

  // usingstd::find with vector and iterator:

 std::vector<int> myvector (myints,myints+4);

 std::vector<int>::iterator it;

 

  it = find(myvector.begin(), myvector.end(), 30);

  if (it !=myvector.end())

    std::cout<< "Element found in myvector: " << *it << '\n';

  else

    std::cout<< "Element not found in myvector\n";

 

  return 0;

}

2

adjacent_find

在iterator对标识元素范围内,查找一对相邻重复元素,找到则返回指向这对元素的第一个元素的迭代器。否则返回past-the-end。

bool myfunction (int i, int j) {

  return (i==j);

}

 

int main () {

  int myints[] ={5,20,5,30,30,20,10,10,20};

 std::vector<int> myvector (myints,myints+8);

 std::vector<int>::iterator it;

 

  // using defaultcomparison:

  it =std::adjacent_find (myvector.begin(), myvector.end());

 

  if(it!=myvector.end())

    std::cout<< "the first pair of repeated elements are: " << *it<< '\n';

 

  //using predicatecomparison:

  it =std::adjacent_find (++it, myvector.end(), myfunction);

 

  if(it!=myvector.end())

    std::cout<< "the second pair of repeated elements are: " << *it<< '\n';

 

  return 0;

}

random_shuffle

对指定范围内的元素随机调整次序。

例1

vector<int> vecInt;

                   vecInt.push_back(1);

                   vecInt.push_back(3);

                   vecInt.push_back(5);

                   vecInt.push_back(7);

                   vecInt.push_back(9);

 

                   stringstr("itcastitcast ");

        

                   random_shuffle(vecInt.begin(),vecInt.end());   //随机排序,结果比如:9,7,1,5,3

                   random_shuffle(str.begin(),str.end());                //随机排序,结果比如:" itstcasticat"

 

reverse

1

           vector<int> vecInt;

                   vecInt.push_back(1);

                   vecInt.push_back(3);

                   vecInt.push_back(5);

                   vecInt.push_back(7);

                   vecInt.push_back(9);

 

                   reverse(vecInt.begin(),vecInt.end());               //{9,7,5,3,1}

 

fill

将输入值赋给标志范围内的所有元素。

                   vector<int>vecIntA;

                   vecIntA.push_back(1);

                   vecIntA.push_back(3);

                   vecIntA.push_back(5);

                   vecIntA.push_back(7);

                   vecIntA.push_back(9);

                   fill(vecIntA.begin(),vecIntA.end(), 8);               //8, 8,8, 8, 8

 

2. #include <functional>

Bind()

typedef struct _Mystruct

{

   voidadd1(int a)

   {

       cout<<a<<endl;

   }

 

   voidadd2(int a,int b)

   {

       cout<<a<<"  "<<b<<endl;

   }

}Mystruct;

void testbind(int a,int b)

{

   cout<<a<<""<<b<<endl;

}

Int main()

{

       using namespace std::placeholders;    // adds visibility of _1, _2, _3,...

       auto test=bind(testbind,_1,_2);

       test(10,15);

 

        Mystruct testt;

        autotestfun=bind(&Mystruct::add1,&testt,_1);

 

}

 

 

3. #include <numeric>

 

例如:

           vector<int> vecIntA;

                   vecIntA.push_back(1);

                   vecIntA.push_back(3);

                   vecIntA.push_back(5);

                   vecIntA.push_back(7);

                   vecIntA.push_back(9);

                   intiSum = accumulate(vecIntA.begin(), vecIntA.end(), 100);          //iSum==125

 

4.  

5.      各种容器运用时机

²    deque的使用场景:比如排队购票系统,对排队者的存储可以采用deque,支持头端的快速移除,尾端的快速添加。如果采用vector,则头端移除时,会移动大量的数据,速度慢。

²  vector与deque的比较:

²  一:vector.at()比deque.at()效率高,比如vector.at(0)是固定的,deque的开始位置却是不固定的。

²  二:如果有大量释放操作的话,vector花的时间更少,这跟二者的内部实现有关。

²  三:deque支持头部的快速插入与快速移除,这是deque的优点。

²  list的使用场景:比如公交车乘客的存储,随时可能有乘客下车,支持频繁的不确实位置元素的移除插入

²  set的使用场景:比如对手机游戏的个人得分记录的存储,存储要求从高分到低分的顺序排列。 

²  map的使用场景:比如按ID号存储十万个用户,想要快速要通过ID查找对应的用户。二叉树的查找效率,这时就体现出来了。如果是vector容器,最坏的情况下可能要遍历完整个容器才能找到该用户。

 

<think>好的,用户让我介绍一下C++ STL常用算法详解。首先,我需要确定用户的需求是什么。他们可能正在学习C++,或者在实际编程中遇到了需要用到STL算法的问题。STL算法有很多,用户可能希望了解最常用的部分,以及具体的用法和例子。 接下来,我应该考虑如何组织内容。通常,分类介绍会比较清晰,比如分为非修改序列操作、修改序列操作、排序和查找、数值操作等。这样用户可以根据需求快速找到需要的算法。 然后,每个算法需要给出功能描述、参数说明和示例代码。示例代码很重要,能帮助用户理解如何使用这些算法。需要注意的是,示例代码应该简洁,并且覆盖常见的使用场景。 可能用户对某些高级用法不太熟悉,比如lambda表达式在算法中的应用,或者自定义谓词的使用。因此,在例子中加入这些元素会更有帮助。比如在sort或transform中使用lambda,可以展示更灵活的应用方式。 还要注意提到C++版本的变化,比如C++11引入的lambda和范围for循环,以及C++17的并行算法特性。这有助于用户了解不同版本中的支持情况,避免兼容性问题。 用户可能容易混淆某些算法,比如remove和erase的区别,需要特别说明。remove只是移动元素,返回新的逻辑结尾,而erase才是真正删除元素。这种常见误区需要强调,避免用户犯错。 另外,数值操作部分如accumulate和inner_product可能在实际项目中应用较多,比如统计和矩阵运算。给出具体的例子能帮助用户联想到实际应用场景。 最后,总结部分可以强调STL算法的优势,比如高效、类型安全和可扩展性,鼓励用户多加练习。同时,提醒他们查阅官方文档以获取更详细的信息。 检查是否有遗漏的重要算法,比如all_of/any_of/none_of这些C++11新增的算法,以及copy和replace系列函数。确保覆盖最常用的部分,同时不过于冗长。 现在需要将这些思考整理成一个结构清晰、内容详实的回答,使用用户友好的语言,避免过于技术化的术语,同时保持准确性。确保代码示例正确,并且解释到位,让不同水平的读者都能有所收获。</think>C++ STL(Standard Template Library)提供了丰富的算法库,能够高效处理容器数据。以下是对常用算法的分类详解及示例: ### 一、非修改序列操作 1. **遍历操作** ```cpp for_each(v.begin(), v.end(), [](int x){ cout << x * 2 << " "; // 所有元素乘2输出 }); ``` 2. **条件判断** ```cpp // 检查是否全为偶数 bool allEven = all_of(v.begin(), v.end(), [](int x){ return x % 2 == 0; }); ``` 3. **元素查找** ```cpp auto it = find(v.begin(), v.end(), 42); // 查找第一个42 auto it2 = find_if(v.begin(), v.end(), [](int x){ return x > 100; }); // 找第一个>100的元素 ``` ### 二、修改序列操作 1. **元素填充** ```cpp fill(v.begin(), v.begin()+5, 0); // 前5个元素填0 ``` 2. **元素复制** ```cpp vector<int> dest(10); copy(v.begin(), v.end(), dest.begin()); // 支持不同类型容器复制 ``` 3. **元素替换** ```cpp replace(v.begin(), v.end(), 5, 10); // 所有5替换为10 ``` ### 三、排序与查找 1. **快速排序** ```cpp sort(v.begin(), v.end(), [](int a, int b){ return a > b; // 降序排列 }); ``` 2. **二分查找** ```cpp bool found = binary_search(v.begin(), v.end(), 42); // 需先排序 ``` 3. **合并有序序列** ```cpp vector<int> v1 = {1,3,5}, v2 = {2,4,6}, result(6); merge(v1.begin(), v1.end(), v2.begin(), v2.end(), result.begin()); ``` ### 四、数值操作 1. **累加计算** ```cpp int sum = accumulate(v.begin(), v.end(), 0, [](int a, int b){ return a + (b % 2 == 0 ? b : 0); // 仅累加偶数 }); ``` 2. **内积计算** ```cpp vector<int> a{1,2}, b{3,4}; int dot = inner_product(a.begin(), a.end(), b.begin(), 0); // 1*3 + 2*4=11 ``` ### 五、特殊操作 1. **元素移除** ```cpp auto new_end = remove(v.begin(), v.end(), 0); // 逻辑删除0 v.erase(new_end, v.end()); // 物理删除 ``` 2. **序列反转** ```cpp reverse(str.begin(), str.end()); // 反转字符串 ``` 3. **去重操作** ```cpp sort(v.begin(), v.end()); auto last = unique(v.begin(), v.end()); // 需先排序 v.erase(last, v.end()); ``` ### 六、高级用法 1. **谓词组合**(C++11) ```cpp auto isEvenAndPositive = [](int x){ return x > 0 && x % 2 == 0; }; count_if(v.begin(), v.end(), isEvenAndPositive); ``` 2. **并行处理**(C++17) ```cpp vector<int> bigData(1'000'000); sort(execution::par, bigData.begin(), bigData.end()); // 并行排序 ``` ### 使用技巧 1. 配合迭代器适配器: ```cpp copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(v)); ``` 2. 类型推导优化: ```cpp auto it = min_element(begin(v), end(v)); // 自动推导迭代器类型 ``` 3. 视图处理(C++20 Ranges): ```cpp auto even = v | views::filter([](int x){ return x%2 == 0; }); ``` 注意要点: - 修改类算法通常返回迭代器,需配合erase使用 - 涉及比较的算法可自定义比较函数 - 算法复杂度从O(n)到O(n log n)不等,需根据数据量选择 - 使用前确保容器已正确初始化 - 注意迭代器失效问题 建议结合具体需求选择算法,例如需要稳定性时选择stable_sort,大数据量时考虑partial_sort。熟练掌握STL算法可提升代码效率和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值