CPP STL學習筆記

STL的概念

源地址  https://www.ev0l.art/index.php/archives/15/php

<li> Iterator (迭代器)
<li> Container (容器) array
<li> Alogrithm (算法)
<li> Adapters (配接器) 用來實現容器之間的轉接

面向過程--》面向對象-》基於對象-》泛型css

代碼

#include <iostream>
#include <vector> //容器 #include <algorithm> //算法 using namespace std; //專麼實現一個類模板,實現打印 //類模板實現了方法 template <class T> class vector_s { public: void operator()(const T &t1) //重載了小括號 實現訪問小括號就直接打印  { cout << t1 << endl; } }; int main(void) { vector<int> myv; myv.push_back(13); myv.push_back(23); myv.push_back(33); myv.push_back(113); myv.push_back(1995); myv.push_back(1996); vector_s<int> print; // 對打印實現實例化 //myv.begin(), myv.end() 是迭代器 本質是指針 // for_each 本質是一個算法  for_each(myv.begin(), myv.end(), print); cin.get(); return 0; }

 


<li>注意:算法須要包含頭文件 <algorithm>

<li>這個遍歷的函數爲 for_each 不是foreach

<li>算法能夠適用於任何容器ios

STL抽象的是什麼

-有些算法並不依賴於數據結構的特定實現,而只依賴於該結構的幾個基本語義屬性git

-STL 抽象出的這些基本屬性(concept)成功的將算法和數據結構相分離,在沒有效率損失的前提下,得到了極大的彈性!算法

六大組件

-容器 (container)編程

-算法Algorithm數組

-迭代器 (iterator)數據結構

-仿函數 (Function Object)less

-適配器 (Adaptor)ide

-空間制配器 (allocator)

獲取遠程代碼修改後,想要push到遠端與原來不一樣的新分支,可使用下面的命令實現:
git push origin 本地分支:遠端但願建立的分支

例如git下來的分支爲master

git branch master
git push origin master:my_remote_new_branch

遠端便可建立新的分支my_remote_new_branch,提交本地修改

2019.11.13 9:32

std::for_each(arr.begin(), arr.end(), func);

比較有用的for_each 用法

for (auto n:Original)

C++ 11 新的for

2019.11.03 23:46

typename

  • 成員函數也能夠是模板-
  • typename 做爲類型前的標識符號-
class MyClass typename T::SubType * ptr; //typename 直接指示 T::SubType * 爲一個類型 沒有typename 會被解析爲 // T域中的 SubType 靜態成員 乘於(*) ptr. ... };

-typename 的第二個做用:在模板聲明中替換class -

template <typename T > class Myclass;

static_cast 只有當類型轉換有所定義,轉換纔會成功。(明確轉換類型)

dynamic_cast 將多態類型向下轉換<downcast> 被轉換的類必須有虛函數。不然失敗

const_cast 用於轉換爲const 值

reinterpret_cast 多用於指針個的轉換

C語言的小括號()能夠替換除dymanic_cast 外的全部靜態轉換函數,沒法明確顯示使用他們的切確理由

容器的概念

-用於管理一組元素
container.jpg

容器的分類

-序列式容器(Sequence containers)

-每一個元素都有固定位置--去結餘插入時機和地點,和元素值無關
-vector list deque

關聯式容器 (Associated containers)

-元素取決於特定的排序準則,和插入順序無關
-set multiset map multimap
container1.jpg

array

array <int ,5>={1,2,3,4,5};
-靜態數組,棧上

vector 動態數組 堆上

mv.push_back()

-不須要變長,容量較小,array 須要變長,容量較大,用vector

tuple 能夠存儲不一樣的數據類型

list 適合常常插入,常常刪除的狀況

list 容器

-list容器是無序容器

-list 容器只能經過迭代器訪問。經過++ -- 遍歷

-list容器可使用remove()方法刪除元素,

-能夠同時正向和反向查找

-可使用sort()函數排序

-可使用merge 合併,可是合併以前必須排序

-可使用unique()函數刪除重複項,刪除前必須排序。

  • merge (使)合併,結合,併入;相融;融入;漸漸消失在某物中

set 容器 (紅黑樹容器)

-set容器不能有重複項,重複的會被捨棄
-set容器會自動排序
-set 用insert插入元素
-set能夠用find()函數查找位置

循環加棧

algorithm 算法

find()函數能夠查找數組、容器中的元素。

for_each(); 遍歷每個元素。

multiset和set差很少,可是容許重複元素。

迭代器本質是智能指針。

Iterator

iterator.jpg

仿函數

auto ifind=find_if(mylist.bengin(),mylisy.end(),bindlst(greater<int>(),3));

bindlst 須要頭文件 funtional #include <functional>

bindlst(greater<int>(),3); 綁定一個函數。 greater<int>() 是一個仿函數(functional) 是一個重載了()的類/結構 體 ,能夠用來實現必定的算法策略。

仿函數例子:

#include <list>
#include <functional> #include <array> #include <algorithm> using namespace std; class shuchu { public: void operator()(int x) { std::cout<<x<<endl; } }; int main(int argc, char const *argv[]) { /* code */ // array<int,5>array1({1,2,3,4,5}); list <int>ls1; ls1.push_back(1); ls1.push_back(3); ls1.push_back(5); ls1.push_back(7); ls1.push_back(9); auto ib=ls1.begin(); auto ie=ls1.end(); for_each(ib,ie,shuchu()); cin.get(); return 0; }

 

2019.11.15 6.wmv STL Bug 迭代器

-智能指針有一個_Ptr屬性,能夠打印裏面的指針。

-STL 有bug 先訪問迭代器的_Ptr屬性,再訪問迭代器指針正常,可是反過來會出錯。

-分行打印就沒有問題。

棧隊列雙端隊列優先隊列

stack 關鍵字能夠構建棧

-用法

stack <mystack>; //聲明一個棧
mystack.push(num); //壓棧
mystack.pop(); //出棧
mystack.top(); //獲取第一個元素

stack成員函數示例
-size( ) :返回棧中元素個數
-top( ) :返回棧頂的元素
-pop( ) :從棧中取出並刪除元素
-push(e) :向棧中添加元素e
-empty( ) :棧爲空時返回true

queue 隊列

-queue 英 [kjuː] 美 [kjuː]

n.(人、汽車等的)隊,行列;(儲存的數據)隊列
v.(人、車等)排隊等候;(使)排隊;列隊等待

-queue 須要頭文件 <queue>

-從網上拔來的Queue

queue詳解

<h2>queue 操做</h2>
queue 和 stack 有一些成員函數類似,但在一些狀況下,工做方式有些不一樣:

  • front():返回 queue 中第一個元素的引用。若是 queue 是常量,就返回一個常引用;若是 queue 爲空,返回值是未定義的。
  • back():返回 queue 中最後一個元素的引用。若是 queue 是常量,就返回一個常引用;若是 queue 爲空,返回值是未定義的。
  • push(const T& obj):在 queue 的尾部添加一個元素的副本。這是經過調用底層容器的成員函數 push_back() 來完成的。
  • push(T&& obj):以移動的方式在 queue 的尾部添加元素。這是經過調用底層容器的具備右值引用參數的成員函數 push_back() 來完成的。
  • pop():刪除 queue 中的第一個元素。
  • size():返回 queue 中元素的個數。
  • empty():若是 queue 中沒有元素的話,返回 true。
  • emplace():用傳給 emplace() 的參數調用 T 的構造函數,在 queue 的尾部生成對象。
  • swap(queue<T> &other_q):將當前 queue 中的元素和參數 queue 中的元素交換。它們須要包含相同類型的元素。也能夠調用全局函數模板 swap() 來完成一樣的操做。



queue<T> 模板定義了拷貝和移動版的 operator=(),對於所保存元素類型相同的 queue 對象,它們有一整套的比較運算符,這些運算符的工做方式和 stack 容器相同。

deque 雙端隊列

  • deque 能夠從頭部push_front()和尾部push_back()插入
  • deque 可使用迭代器 可使用 迭代器+n 訪問刪除
  • deque 能夠pop_front() pop_back() 從頭部和尾部 刪除元素。

(1)    構造函數

deque():建立一個空deque

deque(int nSize):建立一個deque,元素個數爲nSize

deque(int nSize,const T& t):建立一個deque,元素個數爲nSize,且值均爲t

deque(const deque &):複製構造函數

(2)    增長函數

void push_front(const T& x):雙端隊列頭部增長一個元素X

void push_back(const T& x):雙端隊列尾部增長一個元素x

iterator insert(iterator it,const T& x):雙端隊列中某一元素前增長一個元素x

void insert(iterator it,int n,const T& x):雙端隊列中某一元素前增長n個相同的元素x

void insert(iterator it,const_iterator first,const_iteratorlast):雙端隊列中某一元素前插入另外一個相同類型向量的[forst,last)間的數據

(3)    刪除函數

Iterator erase(iterator it):刪除雙端隊列中的某一個元素

Iterator erase(iterator first,iterator last):刪除雙端隊列中[first,last)中的元素

void pop_front():刪除雙端隊列中最前一個元素

void pop_back():刪除雙端隊列中最後一個元素

void clear():清空雙端隊列中最後一個元素

(4)    遍歷函數

reference at(int pos):返回pos位置元素的引用

reference front():返回手元素的引用

reference back():返回尾元素的引用

iterator begin():返回向量頭指針,指向第一個元素

iterator end():返回指向向量中最後一個元素下一個元素的指針(不包含在向量中)

reverse_iterator rbegin():反向迭代器,指向最後一個元素

reverse_iterator rend():反向迭代器,指向第一個元素的前一個元素

(5)    判斷函數

bool empty() const:向量是否爲空,若true,則向量中無元素

(6)    大小函數

Int size() const:返回向量中元素的個數

int max_size() const:返回最大可容許的雙端對了元素數量值

(7)    其餘函數

void swap(deque&):交換兩個同類型向量的數據

void assign(int n,const T& x):向量中第n個元素的值設置爲x
 
deque網上扒來的

priority_que 優先級隊列 (不太理解)

  • 優先隊列是按照堆來實現的

紅黑樹容器

set 是一個紅黑樹

set map multi-map 紅黑樹

set的高級用法

  • 紅黑樹,處理純字符串比較少,處理字符串及對象比較多。
  • pair 複合集合
  • 二叉樹查找依賴於有序。 字符串能夠實現有序。
  • pair 也是個類模板!起到獲取插入返回值(boolean)的做用。兩個參數,第一個類型,第二個是比大小的方法
  • set的每個節點就是一個節點
  • 二叉樹的實現語法一直在在在變 。VS2013 能過的 VS2017 就不能過了!~!!mingw 32又能過,代碼以下:
  • set 不能包含一樣的值
  • 0-35:40
#include <set> #include <string> #include <stdio.h> #include <string.h> using namespace std; class strless { public: bool operator () (const char* p,const char* p1) { return strcmp(p, p1) < 0; } private: }; int main(void) { const char* cmd[] = { "nihao","spectrc","calc","good" }; set<const char *, strless>myset(cmd,cmd+4,strless()); auto ib = myset.begin(); auto ie = myset.end(); for (auto i : myset) { cout << i << endl; } return 0; }

 

 

multiset

  • 能夠插入相同的值
  • multiset 的每個節點是一個鏈表
  • 練習代碼以下(mingw 32編譯):
#include <set> #include <string.h> using namespace std; class stu{ public: int id; char p[100]; }; class stuless { public: bool operator ()(const stu &st1,const stu &st2) { return st1.id<st2.id; } }; int main() { stu student[3]={ {99,"zhuang"}, {15,"li"}, {3,"ooooo"} }; stu newstu; newstu.id=100782; strcpy(newstu.p,"nimeide"); multiset<stu,stuless> stu1 (student,student+3,stuless()); stu1.insert(newstu); strcpy(newstu.p,"SBSBSBSB"); stu1.insert(newstu); strcpy(newstu.p,"luo liuo"); stu1.insert(newstu); for(auto i:stu1) { cout<< "\t"<<i.id<<"\t"<<i.p<<endl; } return 0; }

 

 
  • 輸出

-

cout1.jpg

map 映射 multimap 多層映射  9.wmv 53:41

  • map 也是 紅黑樹,可是能同時映射多個數據
  • map 須要頭文件 <map>
  • 映射都是左邊映射到右邊。訪問時用右邊訪問左邊。能夠經過對等的映射查找
  • 示例代碼以下:
#include <string> #include <map> #include <stdlib.h> using namespace std; class worker{ public: int id; string name; string work; }; class winfo{ public: int randid; worker w1; }; int main() { system("chcp 65001"); winfo warr[]={ {1,{10,"李四","mugong"}}, {2,{9,"張三","mugong"}}, {8,{5,"wangermazi","mugong"}}, {20,{3,"gg","mugong"}}, {30,{1,"ww張三","mugong"}} }; map <int,worker> m; for(auto i : warr) { static int n=0; m[warr[n].randid]=warr[n].w1; n++; } auto ib=m.begin(); auto ie=m.end(); for(;ib!=ie;ib++) { cout<<"\t winfo.randid is \t"<<(*ib).first<<" worker info is \t"<<(*ib).second.id<<"\t"<<(*ib).second.name <<"\t"<<(*ib).second.work<<"\t"<<endl; } return 0; }

 

 
  • 輸出

cout2.jpg

pair 關鍵字  9.wmv 01:23:15

  • 用於插入 複雜映射類型
  • multimap set map 每個節點就是一個 pair
  • 用法:
m.insert(pair<const char*,int> ("第一個"),1); m.insert(pair<const char*,int> ("第二個"),2); m.insert(pair<const char*,int> ("第三個"),5); m.insert(pair<const char*,int> ("第四個"),8); 

hash_set 和hash_map  9.wmv 01:33:10

  • 做用:把比較大的數據抽象得比較小
  • hash_set 不會自動排序 查找時一次就足夠了。而set須要 log2n 次
  • 適用於精確查找,一次就能找到。比二分查找要快
  • hash_set 的經典用法 判斷數據是否相等
  • hash_set、hash_map 不會自動排序
  • hash算法依賴於hash_table

equal_range()

  • 找到紅黑樹的鏈表節點,遍歷全部節點
  • first爲鏈表的首節點,second 爲最後一個空節點

string 本質是一個容器

  • C語言中 下列代碼是錯誤的:
char str[54];
str="123456";
  • erase() 函數可刪除字符串。 str1.erase(3,4); erase(str1.begin(),str.begin()+2);
  • replace() 替換函數 str1.replace(3,3,"China");str1.replace(3,"China");
    str1.replace(3,"China"); replace (位置,長度,字符串);
  • str.find() 查找字符串,找到第一個匹配的字符的位置,找不到返回-1;
  • rfind() 反向查找,返回找的的第一個的匹配的字符串的位置。找不到返回-1;
  • find_first_of () 找到第一個並返回所在位置。
  • find_first_not_of () 找到第一個不匹配的並返回所在位置。
  • find_last_of () 找到最後一個匹配的並返回所在位置。
  • find_last_not_of () 找到最後一個不匹配的並返回所在位置。
網上扒來的 string 介紹

GPU編程

  • 能夠利用模板類實現對容器的操做(利用重載括號的方式)

Lamda 表達式 C++ AMP 編程

  • 函數包裝器(LAMDA 表達式,相似JS裏面的匿名函數) : 須要頭文件 <functional>
  • GPU 強項在於並行計算,CPU強項在於單點計算
auto func=[](int a ,int b){ return a+b;}; for_each(myvector.begin(),myvector.end(),[](int a){return a*=2;cout<<a<<endl;});
  • C++ AMP 計算演示 (VS 2017中編譯失敗)
  • VS2017 中錯誤信息:
嚴重性    代碼    說明    項目    文件    行    禁止顯示狀態
錯誤    C3861 「_Access」: 找不到標識符 GPU_hello c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.15.26726\include\amp.h 2616 嚴重性 代碼 說明 項目 文件 行 禁止顯示狀態 錯誤 C3588 在 amp 限制代碼中不支持從「unknown-type」轉換爲「void *」 GPU_hello c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.15.26726\include\amp.h 2616 
#include <amp.h>
#include <iostream>

using namespace std; using namespace concurrency; int main(void) { int a[10] = { 1,2,3,4,5,6,7,8,9,10 }; array_view<int> av(10, a); //GPU 計算結構 AV 存儲到GPU的顯存 /* *[=](index<1>idx) restrict (amp) {av[idx] *= 2; } * [=] 標識直接操做這個數據 * restrict (amp) 標識定位到 GPU進行運算 *這個表達式爲Lambda表達式 */ parallel_for_each(av.extent, [=](index<1> idx) restrict (amp) {av[idx] *= 2; }); for (int i = 0; i < 10; i++) { cout << "\t" << av[i] << endl; } cin.get(); }

 

 

lambda 表達式

  • 網上扒來的lambda 表達式

Lambda 表達式
-lambda 表達式的做用:C++ 11 中的 Lambda 表達式用於定義並建立匿名的函數對象,以簡化編程工做。

  • lambda 語法形式:[函數對象參數] (操做符重載函數參數) mutable 或 exception 聲明 -> 返回值類型 {函數體}

STL算法

  • for_each ....
  • auto i= find_if (myvector.begin(),myvector.end(),[](int v){return v>4;}); //若是找到myvector 中第一個大於四的數據則返回那個數據所在位置的迭代器,不然返回myvector.end();
  • auto i= find_if_not (myvector.begin(),myvector.end(),[](int v){return v>4;}); //若是找到myvector 中第一個小於於四的數據則返回那個數據所在位置的迭代器,否
    則返回myvector.end();
  • sort() 仿函數用於排序。
相關文章
相關標籤/搜索