中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++ STL之vector模板如何使用

發布時間:2022-08-23 17:31:38 來源:億速云 閱讀:149 作者:iii 欄目:開發技術

本篇內容介紹了“C++ STL之vector模板如何使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

vector模板類

STL(標準模板庫)提供了容器、迭代器、函數對象、算法的模板。容器是類似于數組的東西,它可以存儲若干值,STL容器是同質的,即存儲的值的類型相同;迭代器是用來遍歷容器的,它和能遍歷數組的指針類似,是廣義指針;函數對象是類似于函數的對象,可以是類對象和函數指針;算法就是一些能完成特定任務的處方。

我們來看最簡單的容器:vector模板類。

1. vector模板類

1.1 創建模板類

在頭文件vector中定義了vector模板,我們稱之為矢量,它就像是加強版的數組。

創建vector模板對象:

std::vector<int> first;                                // empty vector of ints
std::vector<int> myadd(5);                             //vector of five ints
std::vector<int> second (4,100);                       // four ints with value 100
std::vector<int> third (second.begin(),second.end());  // iterating through second
std::vector<int> fourth (third);                       // a copy of third

一般來說,我們使用前三種方式初始化vector對象,創建好了后數組可以做的它都可以,例如我們可以使用[]隨機訪問數據。

矢量模板類還支持列表初始化語句

std::vector<int> a{1,2,3,4,5};

1.2 STL容器都提供的成員方法

  • size():返回容器中元素數目

  • swap():交換兩個容器的內容

  • begin():返回一個指向容器第一個元素的迭代器

  • end():返回一個表示超過容器尾的迭代器

什么是迭代器?它是一個廣義指針。它可以是指針,也可以是一個可對其執行&ndash;解除引用operator*()和遞增operator++()&ndash;的對象。每一個容器類都定義了一個合適的迭代器,它的類型是一個名為iteratortypedef,其作用域是整個類。

我們可以這樣聲明一個迭代器:
vector<double>::iterator pd;
也可以使用auto關鍵字:
auto pd=scores.begin();
我們可以使用迭代器pd進行如下操作:

pd=scores.begin();
*pd=22.3;
++pd;
pd++;
--pd;
pd--;

總之迭代器就相當于是指向容器中元素的指針。

什么是超過結尾(past-the-end)?它是一種迭代器,指向容器中最后一個元素后面那個元素。例如在C風格字符串中,字符串的末尾的\0就是超過結尾指向的元素。end()成員函數會返回超過結尾迭代器。
那么我們的遍歷可以這樣寫:

for(pd=scores.begin();pd!=scores.end(),pd++)
    cout<<*pd;
#include<vector>
#include<iostream>
int main()
{
    using std::cout;
    using std::endl;
    using std::vector;
    vector<double> a{1,2,3,4,5};
    vector<double> b{6,7,8};
    cout<<"a size: "<<a.size()<<endl;
    cout<<"b size: "<<b.size()<<endl;
    cout<<"a :";
    for(vector<double>::iterator i=a.begin();i!=a.end();i++)
        cout<<*i<<" ";
    cout<<"\nb :";
    for(vector<double>::iterator i=b.begin();i!=b.end();i++)
        cout<<*i<<" ";
    a.swap(b);
    cout<<"\nafter swap:"<<endl;
    cout<<"a :";
    for(vector<double>::iterator i=a.begin();i!=a.end();i++)
        cout<<*i<<" ";
    cout<<"\nb :";
    for(vector<double>::iterator i=b.begin();i!=b.end();i++)
        cout<<*i<<" ";
}

a size: 5
b size: 3
a :1 2 3 4 5
b :6 7 8
after swap:
a :6 7 8
b :1 2 3 4 5

以上代碼是測試了,矢量類的一些接口

實際上還有很多接口:例如empty,front,back;可以直接看cplusplus

1.3 vector特有的成員方法

  • push_back():將元素添加到矢量末尾,而且矢量長度會自動增大

  • erase():刪除給定區間內的元素

  • insert():插入指定區間內的元素

push_back()接受一個元素類型的參數,它相當于在矢量的超過末尾的地方加個元素:

vector<double> scores;
double temp=1.23;
scores.push_back(temp);

erase()接受兩個迭代器參數,這兩個迭代器定義了要刪除的區間,第一個迭代器是區間起始處,第二個迭代器是區間終止后的第一個位置,例如a.erase(start,end);是指刪除區間[start,end)左開右閉中的元素,而C++中所說的區間都是這種左開右閉的區間。

scores.erase(scores.begin(),scores.begin()+2);

上面這句代碼就會刪除矢量對象中前兩個元素。

insert()會把指定區間里的元素插到一個位置前面。它接受三個迭代器參數,第一個參數指出新元素的插入位置,第二第三就是區間;

vector<int> old_v;
vector<int> new_v;
...
old_v.insert(old_v.begin(),new_v.begin()+1,new_v.end());

上面這段代碼會把new_v中除了第一個元素外的所有元素插到old_v的第一個元素的前面。

超尾元素的存在,使得在最后一個元素后面插入元素變得簡單:

old_v.insert(old_v.end(),new_v.begin()+1,new_v.end());

#include<vector>
#include<iostream>
int main()
{
    using namespace std;
    vector<int> a;
    a.push_back(1);
    a.push_back(2);
    cout<<"a: ";
    for(auto i=a.begin();i!=a.end();i++)
    cout<<*i;
    cout<<endl;
    vector<int>b{3,4,5,6,7};
    a.insert(a.end(),b.begin(),b.begin()+3);
    cout<<"after insert: ";
    cout<<"a: ";
    for(auto i=a.begin();i!=a.end();i++)
    cout<<*i;
    cout<<endl;
    a.erase(a.begin()+1,a.begin()+3);
    cout<<"after erase: ";
    cout<<"a: ";
    for(auto i=a.begin();i!=a.end();i++)
    cout<<*i;
    cout<<endl;
}

a: 12
after insert: a: 12345
after erase: a: 145   

1.4 STL容器的非成員方法

我們會對容器做很多操作,例如搜索,排序。但是這些功能不會放在成員方法中,因為不同的容器類的排序或者搜索方法都是類似的,所以我們為了節省代碼,就不會為每個容器單獨寫這種成員方法。但是,即使存在執行相同任務的非成員函數,STL容器可能也會定義相同的成員方法,例如vectorswap()成員方法比swap()非成員方法效率高,但是非成員函數讓您可以交換兩個不同類型的容器的內容。

  • for_each():遍歷

  • random_shuffle():隨機排列

  • sort():排序

這些方法都定義在頭文件algorithm中,這就是我們所說的算法。
for_each()接受3個參數,前兩個是定義區間的迭代器,最后一個是指向函數的指針(或者說是函數對象)。for_each()將被指向的函數應用于容器間的各個元素。但是for_each()不能修改容器的元素值。我們可以使用它來代替for循環。

for_each(books.begin(),books.end(),foo);//foo是函數名,即函數地址

這個語法很熟悉,很像基于范圍的for循環:

double prices[5]={4.99,10.99,6.87,7.99,8.49};
for(double x:prices)
    cout<<x<<endl;
for_each(books.begin(),books.end(),foo);//foo是函數名,即函數地址
//等價于
for(auto x:books) foo(x);

但是基于范圍的for循環可以改變容器的內容,我們只需要函數的參數是引用參數foo(int &);
然后我們的代碼:

for(auto &x:books) foo(x);

random_shuffle()接受兩個指定區間的迭代器,并隨機排列區間中的元素,但是random_shuffle()要求容器允許隨機訪問(即使用books[i]可以直接訪問元素)

random_shuffle(books.begin(),books.end());

sort()也要求容器支持隨機訪問
第一個版本的sort()接受兩個指定區間的迭代器,并且使用<運算符對容器中的元素進行升序排列:

vector<int> coolstuff;
...
sort(coolstuff.begin(),coolstuff.end());

這就意味著,如果容器中的元素的類型必須定義operator<()

第二個版本的sort()接受三個參數,它更實用,前兩個參數是指定區間的迭代器,第三個參數是函數指針(或函數對象)。這個函數指針指向一個返回bool值,接受兩個元素的函數,如果true就說明排序正確,如果false就說明排序錯誤。

例如我們希望采用降序排列:

bool compare(double db1,double db2)
{
    if(db1<db2)
        return false;
    else 
        return true;
}
int main(){
vector<double> a{4.99,10.99,6.87,7.99,8.49};
sort(a.begin(),a.end(),compare);
}

或者直接使用函數對象:

sort(a.begin(),a.end(),greater<double>());

這里使用的greater<double>()就是函數對象,它返回了double類型的大于運算。

#include<vector>
#include<iostream>
#include<algorithm>
void show(const int &a)
{
    std::cout<<a<<" ";
}
bool greater(const int &x,const int &y)
{
    return x>y;
}
int main()
{
    using std::vector;
    using std::random_shuffle;
    using std::sort;
    using std::for_each;
    using std::cout;
    vector<int> a;
    for(int i=0;i<20;i++)
        a.push_back(i);
    cout<<"initial: ";
    for_each(a.begin(),a.end(),show);
    random_shuffle(a.begin(),a.end());
    cout<<"\nafter shaking: ";
    for_each(a.begin(),a.end(),show);
    sort(a.begin(),a.end());
    cout<<"\nAscending: ";
    for_each(a.begin(),a.end(),show);
    sort(a.begin(),a.end(),greater);
    cout<<"\nDescending: ";
    for_each(a.begin(),a.end(),show);
}

initial: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19       
after shaking: 12 1 9 2 0 11 7 19 4 15 18 5 14 13 10 16 6 3 8 17 
Ascending: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19     
Descending: 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0  

“C++ STL之vector模板如何使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

河北区| 榆树市| 盐津县| 衡阳县| 满洲里市| 巢湖市| 绥滨县| 鲁山县| 济宁市| 大竹县| 鄂尔多斯市| 绍兴市| 东乌珠穆沁旗| 台北市| 德阳市| 精河县| 响水县| 安仁县| 西宁市| 丹东市| 瑞金市| 汉寿县| 乌兰县| 稷山县| 嘉禾县| 辰溪县| 招远市| 孝义市| 高尔夫| 闽清县| 灵寿县| 两当县| 日土县| 三明市| 阿克| 南丹县| 武邑县| 青河县| 大同县| 潞西市| 河北省|