zoukankan      html  css  js  c++  java
  • C++ STL使用的一点总结

    最近正好做到这道题目1071 Speech Patterns,题目本身没有什么算法思想,但是却很灵活的使用到了STL。之前刷完了PAT的Basic Level后,的确感觉自己在STL的使用上熟练了很多。学会灵活的使用STL,真得让代码简洁了不少呢~~~,做题思路也更清晰了(),所以今天就来总结一下我做的一些算法题中常常用到的STL和容器和方法o( ̄︶ ̄)o
    就从1071 Speech Patterns这道题目说起,这是我ac的代码:

    #include<iostream>
    #include<vector>
    #include<map>
    #include<algorithm>
    using namespace std;
    bool cmp(const pair<string,int> &a,const pair<string,int> &b)
    {
        return a.second==b.second?a.first<b.first:a.second>b.second;
    }
    int main()
    {
         int i,j;
         string speech,word;
         getline(cin,speech);
         map<string,int> mp;
         for(i=0;i<speech.length();i++)
         {
     	    if(!isalnum(speech[i]))
     	        continue;
     	    j=i+1;
             while(isalnum(speech[j]))
                 j++;
             word=speech.substr(i,j-i);
             transform(word.begin(),word.end(),word.begin(),::tolower);
             mp[word]++;
             i=j-1;
         }
         vector<pair<string,int>> vec(mp.begin(),mp.end());
         sort(vec.begin(),vec.end(),cmp);
         printf("%s %d",vec[0].first.c_str(),vec[0].second);
         return 0;
     }
    

    这段代码中涉及到了很多很实用的方法~~~
    下面是我的一丢丢总结 (ง •̀_•́)ง

    1. 判断字符是否是数字、字母、数字+字母
      isalpha( )
      isdigit( )
      isalnum( )

    2. 字符串、字符转换成数字
      stof( )
      atof( )
      所在头文件:cmath

    3. transform( )函数的使用
      大小写转换的方法只能针对字符而言,要想直接对字符串进行操作,就需要使用transform( )方法
      函数模板原型如下:

      template < class InputIterator, class OutputIterator, class UnaryOperator > 
         OutputIterator transform ( InputIterator first1,  // 源容器的起始地址 
                                   InputIterator last1,    // 源容器的终止地址 
                                   OutputIterator result,  // 目标容器的起始地址 
                                   UnaryOperator op );     // 函数指针 
      

    transform最经常使用到的就是大小写转换了:

    string str;
    //函数前面的::一定不能省略了(`・ω・´)
    transform(str.begin( ),str.end( ),str.begin( ),::toupper);
    transform(str.begin( ),str.end( ),str.begin( ),::tolower);
    
    1. 对map按value排序
      对map是不能直接使用sort( )函数进行排序的,要想对map按照value排序,得先把map放进vector中,再按照指定的排序方法,对vector排序
      !!!还有map本身就是按照key的顺序排序的,并不是按照插入的顺序排序的(,,•́ . •̀,,)
      那么再将map放入vector中时要使用pair,pair是将两个值,组合成一个数据,pair的两个成员变量first,second。
      将map放入vector中:

       //写法一
       vector<pair<string,int>> vec;
       map<string,int> mp;
       for(map<string,int>::iterator it=mp.begin( );it!=mp.end( ),it++)
           vec.push_back(make_pair(it->first,it->second);
      
      //写法二
       vector<pair<string,int>> vec(mp.begin( ),mp.end( ));
      
    2. 函数参数尽量写成const &的形式
      函数参数如果不改变值的情况下,尽量写成const &的形式,尤其是cmp这类排序方式的函数中,是可以达到加快排序速度的效果的~~~~
      关于const &形式的参数,之前在看C++primer plus的时候,这里面花了很多篇幅说了这个问题,大家有兴趣可以去看一看(。◕ˇ∀ˇ◕)
      下面是一点点这方面当时看书时做的笔记:
      对于使用传递的值而不做修改的函数:

      • 如果数据对象很小,如内置数据类型或小型结构,则按值传递。
      • 如果对象是数组,则使用指针,因为这是唯一的选择,并将指针声明为指向const的指针。
      • 如果数据对象是较大的结构,则使用const 指针或const引用,以提高程序的效率。
      • 如果数据对象是类对象,则使用const引用。类设计的语义常常要求使用引用,这是c++增加这个特性的主要原因,因此传递类对象标准方式是按引用传递。
    3. unordered_map和map的区别
      我做PAT上的题目时,遇到过不少次因为一个测试点运行超时而不能AC的情况,除了算法复杂度的问题外。最坑的是这些地方o(╥﹏╥)o,花了好久的时间找测试点不过的原因,最后发现把所有的cin和cout换成scanf和printf就ac了,还有这种把map换成unordered_map就ac了的情况。
      那么unordered_map和map在速度上到底有什么区别呢?
      传统的map内部的结构是红黑树,那么查找的时候实际上是二分查找,而且红黑树的每个节点都要存储其父节点、子节点以及自身的红黑性质,造成传统map占用内容较多,空间利用率不高。而unodered_map内部维护的结构是hash表,所以查找起来速度自然就要快~~~
      所以当涉及到大数据的查找问题时,就要考虑使用unordered_map了

    4. 迭代器的使用
      说到STL容器,怎么能不说迭代器呢?
      以vector为例,用迭代器进行遍历
      正向迭代器:

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

    反向迭代器:

    for(vector<int>::reverse_iterator riter=vec.rbegin();vector<vec.rend();riter++)
    

    C++11在循环遍历时新增了一个特性就是使用auto,我觉得这个比iterator使用起来更简单一些~~
    所以我现在一般都用auto,不过要注意一下,iterator it和auto it在使用上还是有区别的,迭代器的it: it->first,但是auto it: it.first
    事实上,auto遍历比迭代器的效率要高一些的,所以可以尽量考虑用auto

    1. set容器
      set容器在查找方面是很有用的~,其内部实现的数据结构是红黑树,插入、删除、查找都比vector快
      set我最常用到的就是find( )函数了,find( )返回一个指向被查找到元素的迭代器,所以如果查找不到的话,返回的是end( )

    好了,暂时就说这么多啦(o)/~

  • 相关阅读:
    面试题示例
    软件测试面试题(简答)
    278. 第一个错误的版本 领扣
    hbase搭建web项目 报500错误 HTTP Status 500
    java API连接虚拟机上的hbase
    java程序连接hive数据库遇到的问题
    java程序向hdfs中追加数据,异常以及解决方案
    创建一个简单的maven的web程序
    java连接hbase时出现....is accessible from more than one module:
    导师双选制系统
  • 原文地址:https://www.cnblogs.com/CuteyThyme/p/11820391.html
Copyright © 2011-2022 走看看