一 multimap
key可以重复
案例: 公司: 销售部:2名 技术研发部:1名 财务部:4名 人员信息:姓名,年龄,电话,工资等组成 通过multimap进行信息的插入,保存,显示 分部门显示员工信息
#include <iostream> #include <string> #include <algorithm> #include <map> using namespace std; class Employee { private: int id; string name; public: Employee(int i, string n) { id = i; name = n; } void show() { cout << "工号:" << id << "姓名:"<<name<<endl; } }; int main(void) { Employee e1(1000,"aa"); Employee e2(1001, "bb"); Employee e3(1002, "cc"); Employee e4(1003, "dd"); Employee e5(1004, "ee"); Employee e6(1005, "ff"); Employee e7(1006, "gg"); Employee e8(1007, "ll"); multimap<string, Employee> m; //销售部有2名员工 m.emplace(make_pair("sale", e1)); m.emplace(make_pair("sale", e2)); //研发部有两名员工 m.emplace(make_pair("development", e3)); m.emplace(make_pair("development", e8)); //财务部有四名员工 m.emplace(make_pair("finance",e4)); m.emplace(make_pair("finance", e5)); m.emplace(make_pair("finance", e6)); m.emplace(make_pair("finance", e7)); cout << m.count("Finance") << endl; for (auto it = m.begin(); it != m.end(); it++) { cout << "部门:" << it->first << endl; it->second.show(); } return 0; }
二 deque
双端数组,接口和vector类似,在头部和尾部非常迅速,但是在中部添加元素比较费时,需要添加头文件#include
#include <iostream> #include <string> #include <deque> using namespace std; int main(void) { int data[5] = { 1,2,3,4,5 }; deque<int> d1; deque<int> d2(data, data + 5); deque<int> d3(10,1); for (auto &d : d2) { cout << d << " "; } cout << endl; d2.emplace_back(6); d2.emplace_front(0); for (auto &d : d2) { cout << d << " "; } cout << endl; d2.pop_back(); d2.pop_front(); d2.front() = 10000; d2.back() = 20000; for (auto &d : d2) { cout << d << " "; } cout << endl; return 0; }
三 容器适配器
stack(LIFO) queue(fifo) priority_queue()
3.1 stack
#include <stack> #include <iostream> #include <time.h> using namespace std; int main(void) { stack<int> s; srand(time(NULL)); int num; for (int i = 0; i < 10; i++) { num = rand() % 10; s.push(num); cout << num << "进栈成功" << endl; } cout << "栈顶元素是:" << s.top() << endl; cout << "栈的大小:" << s.size() << endl; //栈和队列不存在遍历,不存在迭代器 while (!s.empty()) { cout << s.top() << "出栈" << endl; s.pop(); } s.pop(); return 0; }
3.2 队列
#include <queue> #include <iostream> #include <time.h> using namespace std; int main(void) { queue<int> q; for (int i = 0; i < 10; i++) { q.push(i); cout << i << " 进队成功" << endl; } cout << "队头元素:" << q.front() << endl; cout << "队尾元素:" << q.back() << endl; cout << "队列大小:" <<q.size()<< endl; while (!q.empty()) { cout << q.front() << "出队" << endl; q.pop(); } return 0; }
3.3 优先队列
#include <queue> #include <iostream> #include <time.h> using namespace std; int main(void) { //priority_queue<int> p; //priority_queue<int, vector<int>, less<int>> p; //等价于priority_queue<int> p; priority_queue<int, deque<int>, greater<int>> p; srand(time(NULL)); int num; for (int i = 0; i < 10; i++) { num = rand() % 10; p.emplace(num); cout << num << "进队成功" << endl; } cout << "队头元素 " << p.top() << endl; cout << "队列长度:" << p.size() << endl; while (!p.empty()) { cout << p.top() <<"出队"<<endl; p.pop(); } return 0; }
四 异常
4.1 什么是异常
异常处理就是处理程序中错误,所谓错误就是程序运行时发生的一些异常事件(栈溢出,数组下标越界等)
4.2 异常的语法
分为三个部分: 抛出异常:throw 检测异常: try { 可能发生异常的语句 } 捕获异常: catch(异常类型 变量名) { 异常处理语句 } 抛出异常:throw关键字,当执行throw之后,try语句块就会立即结束,运行catch中的异常处理的语句。 throw 表达式、常量、变量 throw的用法和惹他于任内类似,throw是抛出一个值,return是上一级调用的函数
#include <iostream> using namespace std; int Div(int x, int y) { if (0 == y) { //return -1; //throw 0; //抛出异常 throw 'a'; } return x / y; } int main(void) { int a, b; cin >> a >> b; try //把可能出现异常的代码放在try语句中 { cout << Div(a, b) << endl; cout << "hello world" << endl; } catch(int) { cout << "zero exception" << endl; } catch (char) { cout << "char exception" << endl; } cout << "nihao nanjing" << endl; return 0; }
4.3 异常的声明
#include <iostream> using namespace std; //int Div(int x, int y); //可能抛出任何异常 //int Div(int x, int y) throw(int, char); //只能抛出int,char类型的异常 int Div(int x, int y) throw(); //不允许抛出任何异常 int main(void) { int a, b; cin >> a >> b; try //把可能出现异常的代码放在try语句中 { cout << Div(a, b) << endl; cout << "hello world" << endl; } catch(int) { cout << "zero exception" << endl; } catch (char) { cout << "char exception" << endl; } catch (double) { cout << "double exception" << endl; } cout << "nihao nanjing" << endl; return 0; } int Div(int x, int y) throw() { if (0 == y) { //return -1; //throw 0; //抛出异常 //throw 'a'; throw 3.14; } return x / y; }
4.4 异常对象
#include <iostream> using namespace std; int Div(int x, int y); //可能抛出任何异常 //int Div(int x, int y) throw(int, char); //只能抛出int,char类型的异常 //int Div(int x, int y) throw(); //不允许抛出任何异常 class Test { public: Test() { cout << "Test的构造函数" << endl; } Test(const Test &obj) { cout << "Test的拷贝构造" << endl; } void print() { cout << "Test exception" << endl; } ~Test() { cout << "Test的析构函数" << endl; } }; int main(void) { int a, b; cin >> a >> b; try //把可能出现异常的代码放在try语句中 { cout << Div(a, b) << endl; cout << "hello world" << endl; } catch(int) { cout << "zero exception" << endl; } catch (char) { cout << "char exception" << endl; } catch (double) { cout << "double exception" << endl; } /*catch (Test t) //调用拷贝构造函数 { t.print(); }*/ /*catch (Test &t) //推荐 { t.print(); }*/ catch (Test *t) { t->print(); delete t; //需要手动释放 } cout << "nihao nanjing" << endl; return 0; } int Div(int x, int y) { if (0 == y) { //return -1; //throw 0; //抛出异常 //throw 'a'; //throw 3.14; //throw Test(); throw new Test(); } return x / y; }
4.5 标准异常库
#include <iostream> #include <exception> using namespace std; int Div(int x, int y); //可能抛出任何异常 //int Div(int x, int y) throw(int, char); //只能抛出int,char类型的异常 //int Div(int x, int y) throw(); //不允许抛出任何异常 class Exception :public exception { private: string Errmsg; public: Exception(string e) :Errmsg(e) { } virtual const char* what() const throw() //虚函数重写 { return Errmsg.data(); } }; int main(void) { int a, b; cin >> a >> b; try { cout << Div(a,b) << endl; } catch (const std::exception &e) { cout << e.what() << endl; } return 0; } int Div(int x, int y) { if (0 == y) { //return -1; //throw 0; //抛出异常 //throw 'a'; //throw 3.14; //throw Test(); throw Exception("除数不能为0"); throw bad_alloc(); } return x / y; }
4.6 自定义stack
优点: 1.pop()-->返回下一个元素 2.如果stack为空,pop和top会抛出异常
#include <iostream> #include <exception> #include <deque> using namespace std; template <typename T> class Stack { protected: std::deque<T> c; public: class ReadEmptyStack :public exception { public: virtual const char* what() const throw() { return "read empty stack"; } }; //typename std::deque<T>::size_type size() const //类型依赖于模板参数的限定名,前面必须加typename auto size() const { return c.size(); } bool empty() const { return c.empty(); } void push(const T& elem) { c.push_back(elem); } T pop() { if (c.empty()) { throw ReadEmptyStack(); } T elem(c.back()); c.pop_back(); return elem; } T& top() { if (c.empty()) { throw ReadEmptyStack(); } return c.back(); } }; int main(void) { try { Stack<int> st; st.push(1); st.push(2); st.push(3); st.push(4); cout << st.pop() << endl; cout << st.pop() << endl; st.top() = 77; //修改栈顶元素为77 st.push(5); st.push(6); st.pop(); cout << "st.size():" << st.size() << endl; while (!st.empty()) { st.pop(); } st.pop(); } catch (const std::exception& e) { cout << e.what() << endl; } return 0; }
五 string
和vector接口类似,是一种特殊的容器,除了具有vector的内存特性之外,专门用于对字符串的处理操作。
#include <iostream> #include <string> #include <cstring> using namespace std; int main(void) { string s1; string s2("helloworld"); string s3(10, 'a'); string s4(s2); cout << s2 << endl; /*cin >> s1; cout << s1 << endl;*/ s1 += "helloworld"; if (s1 == s2) { } //s1 = s1 + s2; s1 += s2; cout << s1 << endl; //string的存取 string s("helloworld"); cout << s[1] << endl; s[1] = 'x'; for (auto it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; for (auto &s : s) { cout << s << " "; } cout << endl; //string的c_str /*char buf[32] = { 0 }; strcpy_s(buf, s.c_str()); cout << buf << endl;*/ //string 的copy char buf[32] = { 0 }; s.copy(buf, 5); //拷贝前5个字节到buf中 cout << buf << endl; //string的长度 cout << s.length() << endl; cout << s.size() << endl; s.reserve(100); cout << s.capacity() << endl; s.shrink_to_fit(); cout << s.capacity() << endl; if (s.empty()) { cout << "字符串是空" << endl; } //string的赋值 s = "helloworld"; const char *ss = "this is test"; s1.assign(ss); cout << s1 << endl; s1.assign(ss, 7); cout << s1 << endl; s1.assign(5, 'a'); //把5个a赋值给s1 cout << s1 << endl; s1.assign(s2); //把s2 赋值给s1 cout << s1 << endl; s1.assign(s4, 4, 3); //把s4从第四个开始的三个字符赋值给当前字符串 cout << s1 << endl; //string的拼接 s1 += "1234"; cout << s1 << endl; s1 += s2; cout << s1 << endl; s1.append(ss); s1.append(s2); s1.append(ss, 2); //拼接ss的前两个字节 s1.append(s2, 4, 2); cout << s1 << endl; s1.append(10, 'x'); cout << s1 << endl; //string的比较 if (s1 == s2) { } if (s1.compare(s2) > 0) { } if (s1.compare(ss) < 0) { cout << "s1 < ss" << endl; } //string字串 cout << s1.substr() << endl; cout << s1.substr(5, 6)<<endl; //从第五个开始,往后输出6个字符 //string的查找和替换 int p = s1.find('o'); cout << p << endl; p = s1.find('o', 8); //从第八个字符向后找 ,不存在返回-1 cout << p << endl; p = s1.find("ll"); cout << p << endl; p = s1.find(s2); cout << p << endl; p = s1.find(ss); cout << p << endl; p = s1.rfind('o'); cout << p << endl; s1.replace(5, 3, "xxx"); cout << s1 << endl; string s9("helloworldhelloworldhelloworldhelloworldhelloworldhelloworld"); //使用上述任意方法,将s3中所有"world"替换成"x" p = s9.find("world"); while (p != -1) { s9.replace(p, strlen("world"), "x"); p = s9.find("world", p + strlen("x")); } cout << s9 << endl; //string的插入和删除 s1.insert(0, "this is"); cout << s1 << endl; s1.insert(10, s2); cout << s1 << endl; s1.insert(0, 5, 'x'); cout << s1 << endl; s1.erase(s1.begin()); cout << s1 << endl; s1.erase(0, 20); cout << s1 << endl; s1.erase(++s1.begin(),s1.end()); cout << s1 << endl; return 0; }