C++模板
模板是泛型程式設計的基礎,泛型程式設計即以一種獨立於任何特定型別的方式編寫程式碼
模板是建立泛型類或函式的藍圖或公式
可以使用模板來定義函式和類
//函式模板
template <typename type> ret-type func-name(parameter list)
{
// 函式的主體
}
//類别範本
template <class type> class class-name {
.
.
}
C++標準庫
①標準函式庫--繼承自C語言
I/O;字串和字元處理;數學;時間、日期和本地化;動態分配;其他;寬字元函式
②物件導向類庫--類及相關函式的集合
C++ I/O;String類;數值類;STL容器類;STL演算法;STL函式物件;STL迭代器;STL分配器;本地化庫;異常處理類;雜項支援庫
C++ 物件導向類庫
string
可以使用下標和迭代器訪問
string s1; //初始化字串,空字串,可變長
string s2 = "I am wenny"; //直接初始化
string s3 = string(6,'c'); //拷貝初始化
//cin>>s1; //遇到空白停止讀取
cout<<s2;
str.c_str(); //將string型str使用c_str()變為字元陣列,可以使用printf進行輸出
cout<<s2[0]; //可以使用下標引用
s2=s1; //用s1代替s2
s1=s1+s2; //連線s1和s2
getline(cin,s3); //獲取有空白符的一整行內容,按Enter鍵結束輸入,不能輸入字元陣列;輸入遺留在輸入緩衝的換行符消除
getline(cin,s3,'#') //輸入一串字元(無論多少個Enter鍵),只要是在‘#’之前的字元都會讀取並儲存
s3.erase(10,8); //刪除s3[10]開始的8個字元,時間複雜度O(n)
s3.insert(2,"bbb"); //在s3中下標為2的字元前插入字串,時間複雜度O(n)
s3.insert(it,it2,it3); //迭代器,表示串[it2,it3)將被插入在it的位置
cout<<s2.find("am",0); //返回子串位置,第二個引數是查詢起始位置,如果沒有找到返回string::npos;時間複雜度O(nm),n和m分別為str和str2的長度
s2.empty();
s2.size();
s2.substr(pos,len); //從pos號位開始,長度為len的子串,時間複雜度O(len)
s2.replace(pos,len,str2); //從pos號為開始、長度為len的子串替換為str2;時間複雜度O(str.length())
標準模板庫
--實現多種流行和常用的演算法和資料結構
幫助檔案:c++API.chm(最後整理於2/26/2006)
cppreference-zh-20210212.chm
template <typename T>
inline void showset(set<T> v){
for(typename set<T>::iterator it=v.begin();it!=v.end();it++)
cout<<*it<<" ";
cout<<endl;
}
vector
翻譯為向量--”變長陣列“;可以不用初始化就必須指定大小的陣列
可以通過下標和迭代器訪問
常見用途:1.儲存資料:元素個數不確定時 2.用鄰接表儲存圖
//初始化
vector<int> v1;
vector<vector<int>> v2; //相當於變長二維陣列
vector<int> v[100]; //相當於二維陣列,第一維已經固定長度
vector<int> v3={1,2,3,4};
vector<string> v4(3,"hi");
vector<int> v5(4); //預設初始化為0,字串預設為空
//操作
v1.push_back(2); //向末尾新增對物件,時間複雜度O(1)
v1.pop_back(); //刪除尾部的物件,時間複雜度O(1)
v1.empty(); //返回bool值
v3.size(); //返回vector種元素的個數,時間複雜度O(1)
v1.clear(); //刪除所有元素,時間複雜度O(n)
v1.insert(v1.begin(),3); //插入一個或多個元素,時間複雜度O(n)
v1.erase(v1.begin()); //刪除一個或多個元素,時間複雜度O(n)
v1=v3;
//使用了迭代器的迴圈體,不要向迭代器所屬容器新增元素
cout<<v1[0]; //返回v種第0個位置上元素的引用
cout<<(v1==v5); //相等當且僅當元素數量相同且對應位置的元素值都相同
set
翻譯為集合
與vector大致相同,但set中的元素有序且唯一;新增元素時自動排序,元素本來存在則動作不執行
只能通過迭代器訪問
常見用途:需要去重卻不方便直接開陣列
set<int> s1={9,8,7,6,5,4}; //從小到大自動排序
showset(s1);
//cout<<s1[1]; //不能使用下標引用
set<string> s2={"hello","world","apple"}; //字典序排序
showset(s2);
s1.insert(9); //已存在沒有插入動作,時間複雜度O(logn)
showset(s1);
s2.insert("banana"); //新增並排序
showset(s2);
set<int>::iterator it s1.find(2); //返回value對應的迭代器,時間複雜度O(logn)
s1.erase(); //引數是迭代器,時間複雜度為O(1);引數是value,時間複雜度是O(logn)
list
雙向連結串列
list<int> l1={6,7,3,4};
showlist(l1);
list<char> l2(5,'a');
showlist(l2);
l1.sort(); //list自己的排序函式,無引數
showlist(l1);
map
翻譯為對映
運用了hash地址對映的思想,即key-value;
將一個型別的變數對映至另一型別;
map的內部實現是一棵紅黑樹
可以通過下標和迭代器訪問
常見用途:建立字串與整數之間的對映;判斷大整數或其它型別資料是否存在的題目,可以把map當bool陣列用;
void showmap(map<string,int> v){
for(map<string,int>::iterator it=v.begin();it!=v.end();it++)
cout<<it->first<<" "<<it->second<<endl; //first表示key,second表示value
cout<<endl;
}
int main()
{
map<string,int> m1; //第一個引數是key,第二個引數是value
m1["jojo"]=100;
m1["kiki"]=99; //會以鍵從小到大的順序自動排序
cout<<m1["jojo"]<<endl;
cout<<m1.count("wenny"); //判斷是否存在key,返回1或0
cout<<m1["test"]<<endl; //不存在key,則顯示0,但會插入到map中
showmap(m1);
m1.erase("kiki"); //通過關鍵字刪除元素,時間複雜度O(logn);直接刪除迭代器時間複雜度O(1)
showmap(m1);
m1.insert(pair<string,int>("harr",89)); //增加元素
showmap(m1);
m1.clear(); //清空元素
m1.find(b); //確定map中是否有string物件b的對映,若沒有函式返回m1.end();時間複雜度O(logn)
return 0;
}
queue
翻譯為佇列,實現先進先出
常見用途:實現廣度優先搜尋
queue<int> q1;
q1.front(); //因為是限制性資料結構,只能通過front()來訪問隊首元素,back()來訪問隊尾元素
q1.back();
q1.push(1);
q1.pop();
q1.empty();
q1.size();
priority_queue
優先佇列,底層用堆實現;隊首元素一定是優先順序最高的那個
常見用途:貪心問題;對dijkstra演算法進行優化
priority_queue<int,vector<int>,greater<int>> q; //從大到小排序,數字越小優先順序越大
priority_queue<int,vector<int>,less<int>> q2; //從小到大排序,數字越大優先順序越大;預設
q.push(3); //入隊,時間複雜度O(logn)
q.push(2);
q.push(4);
cout<<q.top(); //獲得隊首元素,即堆頂元素
q.pop(); //出隊,時間複雜度O(logn)
cout<<q.top();
cout<<q.empty();
struct fru{
string name;
int price;
bool operator < (const fru &b) const{
return price>b.price;
}
};
priority_queue<fru> q3; //按照過載的運算子<排序
fru f1,f2,f3;
f1.name = "peach";
f1.price = 3;
f2.name = "apple";
f2.price = 1;
q3.push(f1);
q3.push(f2);
cout<<endl<<q3.top().name<<" "<<q3.top().price;
struct cmp{
bool operator () (const fru &a,const fru &b){
return a.price>b.price;
}
};
priority_queue<fru,vector<fru>,cmp> q4; //重寫排序規則
q4.push(f1);
q4.push(f2);
cout<<endl<<q4.top().name<<" "<<q4.top().price;
stack
棧,後進先出
常見用途:模擬實現一些遞迴
stack<int> s;
s.push(1); //入棧,時間複雜度O(1)
s.push(2);
s.push(3);
s.pop(); //出棧,時間複雜度O(1)
cout<<s.top()<<endl; //獲得棧頂元素,時間複雜度O(1)
cout<<s.empty()<<endl;
cout<<s.size()<<endl;
pair
可以看作一個內部有兩個元素的結構體
常見用途:用來代替二元結構及其建構函式,節省編碼時間;作為map的鍵值對進行插入
struct pair{
typename first;
typename second;
};
pair<string,int> p;
p.first = "haha";
p.second = 5;
p = make_pair("xixi",55); //臨時構建一個pair
p = pair<string,int>("heihei",555); //臨時構建一個pair
cout<<(p1>=p2); //可以直接使用比較運算元
algorithm下的常用函式
int x=-1,y=2;
double a=0.1,b=0.2;
max(x,y); //引數只能是兩個
min(a,b);
abs(x); //x必須是整數
swap(x,y); //交換x和y的值
int c[3]={1,2,3};
reverse(c,c+3); //將陣列指標在[it,it2)之間的元素或容器的迭代器在[it,it2)範圍內的元素進行反轉
int d[10]={1,2,3};
do{
cout<<a[0]<<a[1]<<a[2]<<endl;
}while(next_permutation(d,d+3)); //函式給出一個序列在全排列中的下一個序列,到達全排列最後一個時會返回false
fill(d,d+2,5); //把陣列或容器的[it,it2)賦為某個相同的值
sort(d,d+3); //預設遞增排序
//用在有序陣列或容器中;時間複雜度O(log(last-first));返回位置的指標或迭代器
lower_bound(d,d+3,2); //尋找第一個大於等於val的元素位置
upper_bound(d,d+3,2); //尋找第一個大於val的元素位置