目录
string的基本用法:
array的基本方法
与c++语言内置的数组一样, array类模版支持几乎所有内置数组包含的特性,array为c++11新特性
- 顺序的(sequence)
- 内存连续的(contiguous storage)
- 固定大小的(fixed-size)
- array::begin
- array::end
- array::cbegin
- array::cend
- array::rbegin
- array::rend
- array::crbegin
- array::crend
- 与其他容器的差异
-
该方面的差异主要体现在swap成员函数上。其他容器调用swap函数时,为了保证高效,实际上执行的操作相当于交换指向实际容器内容的指针。但是array的swap函数却是进行逐成员交换,这也许是为了保持与内置数组相同的性质----数组地址不可变。
#include"iostream" #include"iterator" #include"array" using namespace std; //标准库arrey:非类 类型容器,不提供内存管理,固定大小 头文件"arrey" //包装了内置数组,固定大小容器所以不支持构造函数,与STL接轨,容器 void array_operator() { array<int, 10>a = {0,1,2,3,4,5,6,7,8,9};//定义一个数组,大小和类型 array<int, 10>b = { 0 }; array<int, 10>c; array<int, 10>d; array<int, 0>f;//支持空数组 b = a;//支持赋值交换 c = { 1,2,3,4,5,6,7,8,9,0 };//列表赋值 cout << c.front() << " "<<c.back()<<endl; for (auto temp : b)//遍历for范围语句 cout << temp; c.fill(9);//.fill for (int i=0;i<c.size();i++)//for循环下标 cout << c[i]; d.swap(c);//数组交换 for (auto iter = d.begin(); iter != d.end(); iter++)//迭代器 cout << *iter; for (auto iter = a.rbegin(); iter != a.rend(); iter++)//迭代器倒序 cout << *iter; } //内置数组 使用数组的时候编译器会把它转换为指针 //数组名:指向数组首元素的地址 //指针也是迭代器 也可以取到尾后指针 void pointer_end() { int a[10] = { 1,2,3,4,5,6,7,8,9,0 }; int *p = &a[10];//取尾后指针,不指向任意元素 for (int *b = a; b != p; b++) cout << *b; cout << endl; } //数组不是类类型表准库函数 begin end也是全局函数 void begin_end() { int a[10] = { 1,2,3,4,5,6,7,8,9,0 }; int *beg = begin(a);//返回首元素地址 int *last = end(a);//返回尾后指针 while (beg != last) cout << *beg++; } //多维数组:数组的数组 //多维数组下标引用 表达式下标维度比数组维度比较小,则表达式结果给一个内层数组的索引 void arrey_index() { int a[2][3] = { 1,2,3,4,5,6 }; int(&b)[3] = a[1];//b为包含3个整形元素数组的引用 int *p = a[1]; for (auto c : b) cout << c; for (int i = 0; i < 3; i++) cout << *p++; for (int i = 0; i < 3; i++) cout << *(a[1] + i); for (auto &row : a)//对多维数组使用for范围语句,除了最内层for其他都用引用 for (auto &col : row)//若最外层不是&则,编译器将row转换为一个指针int* cout << col; //若是引用row指向一个长度为3的数组,类似于int(&b)[3] }
vector等线性容器的基本方法比较:
-
顺序容器
vector 可变大小数组,支持快速随机访问
deque 双端队列,支持快速随机访问
list 双向链表,双向顺序访问
forward_list 单项链表,单项顺序访问
arrey 固定大小数组
string 与vector相似的容器,保存字符串,随机访问类型别名:必须显示的使用类型名(作用域)
eg list<string>::iterator iter; vector<int>:reference a = b;
iterator const_iterator
size_type 无符号整形,存储容器大小类数据
difference_type 带符号整形,保存两个迭代器之间的距离
value_type 元素类型
reference元素的左值类型 value_type&含义相同
const_reference初始化:C c; C c(c2); C c(b,e)迭代器b和e之间。C c{a,c,c,e,e...}初始化列表,新标准支持
赋值与交换
c1 = c2;c1 = {a,x,c,d,e} c1中的元素替换assign()除了arrey其他顺序容器均可
从不同但相容的类型赋值,或者拷贝子序列
v.assign(v2.begin(),v2.end())
v.assign(v3.begin(),10,"Hellow")//10个Hellow初始化赋值a.swap(b); swap(a,b)//尽量使用非成员版的//别的容器交换是迭代器交换,arrey则是值交换
vector
.push_back() pop_back() vector
.front() .back() v.empty()
大小
c.size() (不支持forward_list) c.max_size()c可以保存的最大数目
c.insert() c.erase() c.clear()删除c中所有元素,返回void
> = < >= <=迭代器
begin end 迭代器(尾后迭代器,左闭右开)cbegin cend 返回const_iterator类型
c.rbegin() c.rend()逆序迭代器(不支持forward_list) c.crbegin() c.crend()
-
#include"iostream" #include<stdlib.h> #include<time.h> #include"vector" using namespace std; int randNum() { // int flags[11];//标志位 int i = 0; int Y = 30; int X = 10; int temp; //验证确实生成了[20,30]的随机数 temp = rand() % (Y - X + 1) + X;//生成[10,30]的随机数 return temp; } //头元素尾元素的读取修改和删除 void getElement() { vector<int>v1; for (int i = 0; i < 5; i++) { v1.push_back(randNum());//从尾部插入v1.push_back() 自动扩充大小不用提前分贝内存 } cout << v1.front() << endl;//获取头部元素 v1.front() v1.front() = 11; //v1.front()当左值 修改头部元素 v1.back() = 22; //v1.back()当左值 修改尾部元素 while (v1.size() > 0) { cout << v1.back();//取出尾部元素 v1.back() v1.pop_back();//删除尾部元素(弹出)v1.pop() cout << " vector长度:" << v1.size()<<endl; cout << "vector_maxsize:" << v1.max_size() << endl; } } //初始化 void InitialVector() { vector<int>v1; for (int i = 0; i < 5; i++) { v1.push_back(randNum()); } vector<int>v2 = v1; vector<int>v3(v1.begin(),v1.end()-2); vector<int>v4(10, 0);//10个0 vector<string>v5; v5.assign(10, "hehehe "); for (int i = 0; i < v3.size(); i++) { cout << v3[i] << endl; } } //遍历 void VectorTraverse() { vector<int> v(10);//提前分配内存大小 =进行拷贝 for (int i = 0; i < 10; i++) { v[i] = randNum();//实际是拷贝,所以得提前分配内存 } for (int i = 0; i < 10; i++) { cout << v[i] << " "; } cout << endl; //关于迭代器 //end在最后一个元素的下一个位置 迭代器的种类 //任何使用迭代器的循环体,都不要向容器中添加元素,否则迭代器失效 //迭代器方式正向遍历 for (vector<int>::iterator it = v.begin(); it != v.end(); it++) { cout << *it<<' ';//*t解引用 } for (auto it = v.cbegin(); it != v.cend(); it++)//const_iterator { cout << *it << ' '; } cout << endl; //迭代器方式反向遍历 for (vector<int>::reverse_iterator rit = v.rbegin(); rit != v.rend(); rit++) { cout << *rit<<' '; } cout << endl; } void PrintVector(vector<int>&v) { for (int i = 0; i < v.size(); i++) { cout << v[i] << ' '; } cout << endl; } //插入和删除 void insertAnddelte() { vector<int>v(10); for (int i = 0; i < 10; i++) { v[i] = randNum();//实际是拷贝,所以得提前分配内存 } v.erase(v.begin(), v.end() - 8);//删除指定的区间 PrintVector(v); v.erase(v.begin());//删除指定位置的元素 PrintVector(v); v[1] = 2; v[4] = 2; v[6] = 2; PrintVector(v); for (vector<int>::iterator it = v.begin(); it != v.end();) { if (*it == 2) { it = v.erase(it);//eraser删除之后,将迭代器自动向后移一位 } else it++; } PrintVector(v); //头插和尾插 v.insert(v.begin(), 100); v.insert(v.end(), 100); PrintVector(v); } void main() { //初始化一次就行,否则每次运行时间过短导致产生一模一样的随机数 srand(time(0)); getElement(); InitialVector(); VectorTraverse(); insertAnddelte(); system("pause"); }
string的基本用法:
#include"iostream" #include"string" #include"algorithm" #include"cctype" //c++头问价cname c头文件name.h using namespace std; //os<<s 将s写到输出流os当中,返回os //is>>s 从is 中读取字符串给s,返回is //getline(is,s) 从is中读取一整行赋给s,返回is //s.empty() s为空返回true //s.size() s.length() 长度,基本没区别 //s[n] //s1+s2 s1.append(s2) //s1 == s2 s1!=s2 > < <= >= //修改操作 .erase() .insert() .replace() .append() .assign() //初始化操作 void readString() { cout << "please input Hello World" << endl; string s,s1,s2; cin >> s; //将string 对象读入s。遇到空白(空格换行制表符)停止 cout << s << endl;//Hello cout << "please input Hello World" << endl; cin >> s1 >> s2;//第一个s1 第二个s2链式编程 cout << s1<<s2 << endl;//HelloWorld //读取未知数量string string word; /*while (cin >> word)//流有效则继续读,非法输入或文件结束符标记循环结束crtl+z cout << word; cout << endl;*/ //getline(cin string line)按照行读,遇到换行符停止,从给定的输入流cin读(包括换行符)在将内容读入line string line; while (getline(cin, line)) cout << line << endl; } void StringInitial() { string s1 = "aaaa"; string s2("bcdrfghijklmn"); string s3 = s2;//拷贝构造函数来初始化 string s4(10, 'c'); string s5 = s3.substr(5, 8);//子串初始化 cout << "s1:" << s1 << endl; cout << "s2:" << s2 << endl; cout << "s3:" << s3 << endl; cout << "s4:" << s4 << endl; } void StringTraverse()//遍历操作 { string s = "sbkjbdkjsbkj"; //数组方式遍历 for (int i = 0; i < s.length(); i++) { cout << s[i] <<' '; } cout << endl; //迭代器方式 for (string::iterator it = s.begin(); it != s.end(); it++) { cout << *it << ' '; } cout << endl; //at方式和[]方式的区别 at会越界时返回异常 try catch 时使用较好 //[]方式在刚刚越界返回0,之后越界会直接报错中断程序 try { for (int i = 0; i < s.length()+3; i++) { cout << s.at(i) << ' '; } cout << endl; } catch (...) { cout << "发生异常" << endl; } /*try { for (int i = 0; i < s.length() + 3; i++) { cout << s[i] << ' ';//越界不会报异常,直接出错 } cout << endl; } catch (...) { cout << "发生异常" << endl; }*/ } //字符串的连接 void StringCat() { string s1 = "abcd"; string s2 = "efgh"; string s3 = s2 + "Hello";//字面值 //string s4 = "Hellow"+"world"+s3; //错误保证每个加法两侧至少一个是string string s4 = "Hellow" +s3+ "world"; cout << s1 + s2 << endl; cout << s1.append(s2) << endl; cout << s4; } //char转string void charTostr() { string s = "aaaaabbbbb"; //s ===> char printf("%s", s.c_str());//%s为c风格输出,必须要有\0 string没有不能这样输出 cout << endl; //将string copy到char char buf[256] = { 0 };//最好初始化为0,否则没有拷贝到0,则会缺失c字符串结束符\0 s.copy(buf, 5, 0);//从0开始拷贝5个字符到buf printf("%s", buf); } void char_inSring() { //cctype string str("Hello World!!!"); decltype(str.size())punct_cnt = 0; for (auto c : str)//基于范围的for语句str部分必须是一个序列,c每次自动指向下一个元素 if (ispunct(c)) ++punct_cnt; cout << punct_cnt << endl; //for语句改变字符串,必须用引用 for (auto &c : str) c = toupper(c); cout << str << endl; } void strFind() { //查找 string s = "wchsbdcnswchnalkndcalnwchnskldn"; int index1 = 0; int index2 = 0; index1 = s.find("wch", 0);//从0位置查找wch返回第一个wch的下标,否则返回-1 index2 = s.rfind("wch", 0);//从0位置查找wch返回最后一个wch的下标,否则返回-1 cout << index1 << endl; //查找所有wch位置 string s2 = "wchsbdcnswchnalkndcalnwchnskldn"; int indnex = 0; indnex = s2.find("wch", 0); while (indnex != string::npos)//string的npos为查找失败标志 { cout << indnex << endl; indnex = s2.find("wch", indnex+1);//找到则加1,防止漏掉连续重复的(若寻找aaa aaaaa) } //替换 string s3 = "abcdgfghijk"; s3.replace(4, 3, "efg");//从下标4开始替换3个字符,替换为efg cout << s3 << endl; indnex = s2.find("wch", 0); while (indnex != string::npos)//string的npos为查找失败标志 { s2.replace(indnex, 3, "WCH"); indnex = s2.find("wch", indnex + 1);//找到则加1,防止漏掉连续重复的(若寻找aaa aaaaa) } cout << s2 << endl; s3.assign("ttt");//s3替换成"ttt"同时返回指向s3的引用 } //截断和插入 void eraserAnddelte() { string s1 = "hellowm hellow hellow"; string::iterator it = find(s1.begin(), s1.end(),'m');//调用algorithm的find函数 if (it != s1.end()) { s1.erase(it);//删除 } cout << s1 << endl; s1.erase(s1.begin(), s1.end());//删除s1.begin 到s1.end的所有元素 cout << "s1:" << s1 << "length:" << s1.length() << endl; //插入 string s2 ="BBBB"; s2.insert(0, "AAAA");//在0位置处插入AAAA s2.insert(s2.size(), "BBB"); cout << s2 << endl; } //string和数值之间的转换 void num_string() { //stoi(s,p,b) p默认为0,size_t* 指针用来保存第一个为数字的下标,b基数默认为10 //stol 长整形 stoul stoull string a = "12345"; string b = "0.22379"; size_t * start = (size_t *)3; cout << stoi(a) << endl;//默认 cout << stoi(a, 0, 10) << endl; //stod(s,p) double stof(s,p),stold(s,p) cout << stod(b, 0)<<endl; cout << stof(b) << endl; //数值转换为string to_string() cout << to_string(4328402).size() << endl; cout << to_string(0.72382).size() << endl; } //string 类算法 void algorithmString() { string s1 = "AAAbbb";//调用transform算法 将从s1.begin()到s1.end()的区间内, //转换为大写保存在s1.begin()开头的内存区间 //最后一个参数可以使 1 函数入口地址 2函数对象 3预定义的函数对象 transform(s1.begin(), s1.end(), s1.begin(), toupper);//调用stl的toupper cout << s1 << endl; transform(s1.begin(), s1.end(), s1.begin(), tolower);//调用stl的toupper cout << s1 << endl; } void main() { int i = 0; StringInitial(); StringTraverse(); charTostr(); StringCat(); strFind(); eraserAnddelte(); algorithmString(); readString(); char_inSring(); num_string(); system("pause"); }
-
参考:
-
《c++ primer》
-
C++ Reference