C++ STL vector set map 簡易用法


 

<vector>

std::vector

  動態數組,數組長度可變

 

方法:

  • push_back(i) 在末尾加入一個元素i
  • pop_back()  把末尾元素彈出
  • size() 獲取容器長度
  • claer() 清空容器內容(沒有清理內存)
  • insert(const_iterator position, InputIterator first, InputIterator last)往position位置后插入[first,last)的容器元素

 

重點l 清空內存的方法。

vector<int> v;
vector<int>().swap(v);

 

(一) vector 基礎使用

往vec中添加元素,然后用下標 遍歷輸出。

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> v;
    for(int i=1;i<=10;++i){
        v.push_back(i*i);
    }
    for(int i=0;i<v.size();++i){
        cout << v[i] << " ";
    }
    cout << endl;
    return 0;
}

 

(二).   二維vector 使用

------注意空格,編譯器無法過-------

構造 可變行 可變列。

  vector<vector<T> > v2d (內無元素,只有能push_back后訪問)

構造 n行 m列 , 組內元素都為0。

  vector<vector<T> > v2d(n,vector<T>(m,0))

  vector<vector<T> > v2d(n,vector<T>(n));

構造 n行 可變

  vector<vector<T> > v2d(n,vector<T>())

構造 n行 1列 (因為默認初始值是一個空的一維vector)

  vector<vector<T> > v2d(n);

 

錯誤示范:

    vector<vector<int>> v2d; ------注意空格,編譯器無法過-------

    vector<vector<int> v2d(10,0) ----無法用整形去初始化-----

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<vector<int> > v2d;
    for(int i=0;i < 5; ++i){
        v2d.push_back(vector<int>());
    }
    for(int i=0;i<v2d.size();++i){
        for(int j=0;j<=i;++j){
            v2d[i].push_back( (i+1) * (j+1) );
        }
    }
    for(int i=0;i<v2d.size();++i){
        for(int j=0;j<v2d[i].size();++j){
            cout << i+1 << " * " << j+1 << " = " << v2d[i][j] << "\t";
        }
        cout << endl;
    }
    return 0;
}
1 * 1 = 1                                                                     
2 * 1 = 2       2 * 2 = 4                                                     
3 * 1 = 3       3 * 2 = 6       3 * 3 = 9                                     
4 * 1 = 4       4 * 2 = 8       4 * 3 = 12      4 * 4 = 16                    
5 * 1 = 5       5 * 2 = 10      5 * 3 = 15      5 * 4 = 20      5 * 5 = 25

 

(三).   vector 的erase

earse 刪除后返回的是 刪除元素的下一位。(如果是最后一個元素,則返回 end() )

小心刪除后的 iter 是野指針,所以要重新從 earse

int x = 2;
for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); )
{
     if( *iter == x)
          //刪除iter,erase返回刪除 iter的下一位
          iter = veci.erase(iter); // 返回刪除后剩下的那個元素。
      else
            iter ++ ; //防止刪除最后一個元素的時候,it++
}

 

等價於用remove.

veci.erase(remove(veci.begin(),veci.end(),2),veci.end());

 

 

<set>

std::set

  集合,集合內元素不能重復,

  迭代器遍歷的順序是從小到大(set 容器內元素 自動排序)

 

方法:

  • insert(i)    向集合插入一個元素i       O(logn)
  • erase(i)      刪除元素i            O(logn)
  • count(i)      統計元素i個數             O(logn)
  • size()           獲取容器長度            O(1)
  • clear()         清空容器內容(清理內存)      O(n)

 

(一).   set 的使用實例

#include <iostream>
#include <string>
#include <set>
using namespace std;
int main() {
    set<string> country;
    country.insert("China");
    country.insert("America");
    country.insert("France");
    set<string>::iterator it;
    for(it = country.begin();it!=country.end();++it){
        cout << *it << " ";
    }
    cout << endl;
    country.erase("America");
    country.erase("England");I
    }
    country.clear();
    return 0;
}

 

(二).   set 內的排序定義。

如果要定義Set元素的比較規則,

則需要通過 重載 元素本身的比較操作符 來定義。

重要: 相等的時候要返回 false 否則 count()失效

    確保重載函數每個出口都有返回值。

#include <iostream>
#include <set>

using namespace std;
struct Point{
    int x,y;
    bool operator<(const Point &rhs) const{//重載操作符
        if(x == rhs.x){
            return y < rhs.y;
        }else{
            return x < rhs.x; 
        }
    }
};
int main() {
    int n;
    set<Point> v;
    cin >> n;
    for(int i=0;i<n;++i){
        Point temp;
        cin >> temp.x >> temp.y;
        v.insert(temp);
    }
    for(set<Point>::iterator it = v.begin(); it != v.end(); ++it){
        cout << it->x << " " << it->y << endl;
    }
    return 0;
}

 

判斷集合Cri 是否出現過

#include <iostream>
#include <set>
using namespace std;
const int MAXN = 2e+5 + 1;
const int MAXN2 = 1e4;
int n,m;
struct Cri{
    Cri(int a,int b,int c) : x(a),y(b),z(c){}
    int x;
    int y;
    int z;
    bool operator<(const Cri &rhs) const{
        if(x!=rhs.x)
            return    x < rhs.x;
        if(y!=rhs.y)
            return    y < rhs.y;
        if(z!=rhs.z)
            return    z < rhs.z;
        return false; //相等不要忘記False,否則count會失效
    }
};
set<Cri> cri;
int s[MAXN2];
int main(){
    cin >> n >> m;
    int a,b,c;
    for(int i=0;i<n;++i){
        cin >> a >> b >> c;
        cri.insert(Cri(a,b,c));
    }
    for(int i=0;i<m;++i){
        cin >> a >> b >> c;
        if(cri.count(Cri(a,b,c)))
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
    return 0;
}

 

<map>

std::map

 映射表,key 與 value 有一對一的關系。

 map 默認按照 key 從小到大 順序排列 ( 容器內元素 自動排序)

推薦鏈接:

  • std::map<char,int> first;
  • std::map<char,int> second (first.begin(),first.end());
  • std::map<char,int> third (second);
  • std::map<char,int,classcomp> fourth;
  • insert(i)    插入一對映射       O(logn)
  • count(i)      判斷關鍵字是否存在            O(logn)
  • erase(i)      刪除元素            O(logn)
  • size()           獲取映射對個數            O(1)
  • clear()          清空容器(清理內存)      O(n)

(一).   map 的使用實例

#include <iostream>
#include <string>
#include <map>

using namespace std;
int main() {
    map<string,int> dict;
    dict["Tom"] = 1;
    dict["Jone"] = 2;
    dict["Mary"] = 1;
    if(dict.count("Mary")){
        cout << "Mary is in class " << dict["Mary"];
        dict["Mary"] = 5;
    }
    for(map<string,int>::iterator it = dict.begin();it != dict.end(); ++ it){
        cout << it->first << " is in class " << it->second << endl;
    }
    dict.clear();
    return 0;
}

 

(二).   map 的套用

類似二維vector。> > 之間的空格不能省略

map<int, set<string> > s 

#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
    map<int, map<string,int > > info;
    int n;
    cin >> n;
    for(int i=0;i<n;++i){
        int class_id;
        string name;
        cin >> class_id >> name;
        info[class_id][name]++;
    }

    for(map<int, map<string,int> >:: iterator it1 = info.begin(); it1 != info.end();
        it1++){
        for(map<string,int>::iterator it2 = it1->second.begin(); it2 != it1->second.end();it2++){
            cout << "There are " << it2->second << " people named " << it2->first << " in class " << it1->first << endl;
        }
    }
    return 0;
}

 

(三) map 自動排序

按key排序

(1) 在聲明時,將第cmp函數打包成直接調用的類。

(2) 如果key 是結構體,則可以 重載 operater < (const T &rhs) const {}

 

struct classcomp {
  bool operator() (const string& lhs, const string& rhs) const
  {return lhs<rhs;}
};

map<string,int,classcomp> mp; //從小到大排序

 

按 value 排序,得用sort() 

但是 sort 只能對 序列容器(線性的,例如:vector,queue,list ) 排序。

map雖然是一個集合容器,但是它不是線性存儲的(比如紅黑樹)。

所以只能:

  • 一是通過將 map 轉換到序列容器,再用STL提供的sort方法得以實現的。

  • 二是通過將 map 的 key 和 value 位置替換

typedef pair<string,int> pr;
struct classcomp {
      bool operator() (const pr &lhs, const pr &rhs) const{
          return lhs.second < rhs.second;
    }
};

bool cmp (const pr &lhs, const pr &rhs){
      return lhs.second < rhs.second;
}

map<string,int> mp;

vector<pr> vec;
for(map<string,int>::iterator it = mp.begin(); it != mp.end(); ++it){
    vec.push_back(make_pair(it->first, it->second));
}
sort(vec.begin(),vec.end(),classcomp());
//sort(vec.begin(),vec.end(),cmp );

 

#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int n;
map<string,map<string,int> > mp;
typedef pair<string,map<string,int> > PR;

bool cmp (const PR &lhs,const PR &rhs) {
    if(lhs.first != rhs.first)
        return lhs.first < rhs.first;
}

int main() {
    cin >> n;
    string f,p;
    int num;
    for(int i=0; i<n; ++i) {
        cin >> f >> p >> num;
        mp[p][f]+=num;
    }
    vector<PR> vec;
    for(map<string,map<string,int> >::iterator it = mp.begin(); it!=mp.end(); ++it) {
        vec.push_back(make_pair(it->first,it->second));
    }
    sort(vec.begin(),vec.end(),cmp);
    for(int i=0; i<vec.size(); ++i) {
        cout << vec[i].first << endl;
        map<string,int> &pm = vec[i].second;
        for(map<string,int>::iterator it =  pm.begin(); it != pm.end(); ++it) {
            cout << "   |----" << it->first << "(" << it->second << ")" << endl;
        }
    }
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM