**一、如何在Dev-Cpp中使用C++11中的函数:stoi、to_string、
**unordered_map、unordered_set、auto 如果想要在Dev-Cpp里面使用C++11特性的函数,比如刷算法中常用的stoi、to_string、unordered_map、unordered_set、auto这些,需要在设置里面让dev支持c++11~需要这样做~ 在工具-编译选项-编译器-编译时加入这个命令“-std=c++11”:
二、[C++] STL库函数之字符串string::npos的介绍,以及string中的find函数
npos经常和find一起用~它们两个都在头文件里面~先看用法: #include #include using namespace std;int main() { string s = “abc”; if (s.find(“b”) != string::npos) printf(“字符串s中存在b字符~”); else printf(“字符串s中不存在b字符~”); return 0;} 简单点说就是,在字符串s中查找“b”字符(当然也可以查找一个字符串如“ab”),find函数如果找到了,就会返回第一次出现这个字符的位置,如果没找到怎么办呢,它会返回npos这个位置,npos本质上其实是一个常数,一般来说值是-1,所以s.find(“b”) != string::npos表示找到了“b”这个字符~如果相等就是没找到的意思啦~ 我们可以从C++库函数的官方文档(www.cplusplus.com)中找到对这两个函数的解释~ std::string::find——[Return Value]The position of the first character of the first match.If no matches were found, the function returns string::npos. std::string::nposstatic const size_t npos = -1;As a return value, it is usually used to indicate no matches. 以及关于为什么npos的值是-1的解释: npos is a static member constant value with the greatest possible value for an element of type size_t.This constant is defined with a value of -1, which because size_t is an unsigned integral type, it is the largest possible representable value for this type.
三、【C++】max_element() 和 min_element()
- 在头文件 #include 中,返回的是迭代器,所以输出值的话要在前面加 *1. 第三个参数cmp可写可不写, max_element() 和 min_element() 默认是从小到大排列,然后 max_element() 输出最后一个值, min_element() 输出第一个值,但是如果自定义的 cmp 函数写的是从大到小排列,那么会导致 max_element() 和min_element() 的两个结果是对调的2. 可以用于 vector 或者 vector 等,也可以用于 int arr[4] 或者string arr[4] ,也可以用于结构体vector或者结构体数组~struct node { int x, y;};bool cmp1(node a, node b) { return a.x > b.x;}int main() { vector v(3); int arr[4]; vector v1(3); cout << *max_element(v.begin(), v.end()); cout << *min_element(arr, arr + 4); cout << (*max_element(v1.begin(), v1.end(), cmp1)).y; return 0;}
四、【C++】accumulate函数的用法(STL)
在头文件#include 里(但是我用的时候在PAT里面不写头文件似乎也没关系……)主要是用来累加容器里面的值,比如int、string之类,可以少写一个for循环比如直接统计vector v 里面所有元素的和:(第三个参数的0表示sum的初始值为0)int sum = accumulate(v.begin(), v.end(), 0);比如直接将vector v 里面所有元素一个个累加到string str中:(第三个元素表示str的初始值为空字符串)string str = accumulate(v.begin(), v.end(), “”);
五、binary_search()、upper_bound()、lower_bound() 二分查找
vector a = {0,1,2,2,3,4}; 使用前提是a已经是升序排列 cout << binary_search(a.begin(), a.end(), 3); // 找是否存在3,return false or true auto it = upper_bound(a.begin(), a.end(), 2);// 从左到右返回第一个大于2的数字的地址 auto itt = lower_bound(a.begin(), a.end(), 2);// 从左到右返回第一个大于等于2的数字的地址 // 找不到就返回a.end()
六、sort()、stable_sort()、partial_sort()、nth_element()、greater()、
is_sorted() sort(a, a+5); // 默认从小到大,int数组的排序sort(v.begin(), v.end()); // vector数组排序sort中使用的是快排和插排 stable_sort(v.begin(), v.end()); partial_sort(a, a+2, a+n); // 前2个数字将是正确顺序partial_sort(v.begin(), v.begin() + 3, v.end()); // 对数组中元素部分排序,前3个将是正确顺序 nth_element(v.begin(), v.begin() + 6, v.end()); // 只有v[6]处放置的是正确的元素,其余不管~ sort(v.begin(), v.end(), greater()); // 从大到小排,algorithm头文件 bool flag = is_sorted(a, a+n);bool flag = is_sort(v.begin(), v.end());
七、如何判断cin输入结束
直接判断cin >> a就可以啦 不需要什么EOF和~取反符号哦 输入结束就自动退出循环啦#include using namespace std;int main() { int a; while (cin >> a) { cout << a; } return 0;}、
八、【C++】n_element的用法
n_element函数定义在头文件#include 里面,用法是: n_element(v.begin(), v.begin() + k, v.end()); 表示假设v排序后v[k]应该存储的值为v[k],则n_element函数的作用就是让v[k]这个值放在v[k]处,且让v[k]左边的数都小于v[k],v[k]右边的数都大于v[k]。但是不保证他们是有序的。(即v[k]处存放的是第k+1大的数,并且左边数都比他小右边数字都比他大,比如假设k = 1,表示将v[1]处设置为第2大的数) 也可以自定义添加cmp函数,表示方法为: n_element(v.begin(), v.begin() + k, v.end(), cmp);#include #include #include using namespace std;int main() { vector v{5, 6, 4, 3, 2, 6, 7, 9, 3}; nth_element(v.begin(), v.begin() + v.size()/2, v.end()); cout << "The median is " << v[v.size()/2] << ‘\n’;} 输出为: The median is 5
九、【C++】bitset的用法
bitset用来处理二进制位非常方便。头文件是#include ,在std命名空间里面~#include #include using namespace std;int main() { bitset<5> b(“11”); //5表示5个二进位 // 初始化方式: // bitset<5> b; 都为0 // bitset<5> b(u); u为unsigned int,如果u = 1,则被初始化为10000 // bitset<5> b(s); s为字符串,如"1101" -> “10110” // bitset<5> b(s, pos, n); 从字符串的s[pos]开始,n位长度 for(int i = 0; i < 5; i++) cout << b[i]; cout << endl << b.any(); //b中是否存在1的二进制位 cout << endl << b.none(); //b中不存在1吗? cout << endl << b.count(); //b中到1的二进制位的个数 cout << endl << b.size(); //b中二进制位到个数 cout << endl << b.test(2); //测试下标为2处是否二进制位为1 b.set(4); //把b的下标为4处置1 b.reset(); //所有位归零 b.reset(3); //b的下标3处归零 b.flip(); //b的所有二进制位逐位取反 unsigned long a = b.to_ulong(); //b转换为unsigned long类型 return 0;}
十、【C++】isalpha、islower、isupper、isalnum、isblank、isspace函
数头文件 isalpha、islower、isupper、isalnum、isblank、isspace这些函数都在的头文件里面,下图是它们所表示的范围: 总的来说就是:isalpha 字母(包括大写、小写)islower(小写字母)isupper(大写字母)isalnum(字母大写小写+数字)isblank(space和\t)isspace(space、\t、\r、\n)
十一、【C++】C++中substr的用法
substr有2种用法:假设:string s = “0123456789”;string sub1 = s.substr(5); //只有一个数字5表示从下标为5开始一直到结尾:sub1 = “56789” string sub2 = s.substr(5, 3); //从下标为5开始截取长度为3位:sub2 = “567”
十二、int输出%f浮点值是0,double/float 浮点数%d输出0的原因
include using namespace std;int main() { int a = 3; printf(“int a print float : %f”, a); double b = 3.4; printf("\ndouble b print int : %d", b); return 0;}输出为:int a print float : 0.000000double b print int : 73832int输出%f浮点值的时候,比如2,2内部表示如果看作是float,是个很小的数所以输出的是0.000000double/float 浮点数按照%d输出,如果输出为0,则说明a的数据放在地址的高端,而整型比浮点数内存中占的字节数少,整型只会把属于它的字节数读出来,如在Win32,VC6.0下,Int是4位,它就会把从a开始的4位读出来(按整型格式),所以它把浮点数低端地址的0给输出出来。所以说使用printf的时候数据格式一定要对应,或者使用printf(“%d”, (int)a);这样强制转换的方法输出不同格式的数据
十三、全局变量只能初始化不能赋值
C++中,全局变量只能声明、初始化,而不能赋值 也就是说,下面这样是不被允许的: #include using namespace std;int a;a = 2;int main() { return 0;}12345678910 错误提示是: C++ requires a type specifier for all declarations1声明、初始化与赋值的区别: 声明:int a;初始化:int a = 2;(在声明的时候顺带赋值叫做初始化)赋值:a = 2;只有定义(int a;)才分配存储空间,初始化必须要有存储空间来初始化全局变量在声明时候顺带赋值(也就是初始化)是可以的,但是如果先声明,不赋值,之后再赋值的话,程序是执行不到这里的,也无法通过编译。
十四、容器:
1、【C++ 与 STL】
双端队列:deque
头文件 #include
常用方法:a.push_front(0);//在头部加入数据0
a.push_back(11);//在尾部加入数据11
a.pop_front();//在头部删除数据
a.pop_back();//在尾部删除数据
a.resize(num);//重新指定队列的长度
a.size() //返回容器中实际数据个数
a.max_size() //返回容器中最大数据的数量
#include < iostream> #include < deque> #include < algorithm> using namespace std; int main() { deque<int> a(10); //创建一个有10个元素双端队列a,初始值都为0 //给deque赋值 for (int i = 0; i < a.size(); i++) { a[i] = i + 1; } /输出deque中的数据 for (int i = 0; i < a.size(); i++) { cout << a[i] << " "; } cout << endl;
/在头尾加入新数据 cout << “在头部加入数据0:” << endl;
a. push_front(0);
for (int i = 0; i < a.size(); i++) {
cout << a[i] << " "; }
cout << endl;
cout << “在尾部加入数据11:” << endl;
a.push_back(11);
for (int i = 0; i < a.size(); i++) {
cout << a[i] << " "; } cout << endl;
//在头尾删除数据 cout << "在头部删除数据: " << endl;
pop_front();
for (int i = 0; i < a.size(); i++) { cout << a[i] << " "; } cout << endl;
cout << "在尾部删除数据: " << endl; a.pop_back();
for (int i = 0; i < a.size(); i++) { cout << a[i] << " "; } cout << endl;
//返回容器中实际数据个数 cout << "a.size() = " << a.size() << endl;
//重新指定队列的长度 a. resize(11); for (int i = 0; i < a.size(); i++) { cout << a[i] << " "; } cout <<
endl;
//判断队列是否为空 cout << "a.empty() = " << a.empty() << endl;
//返回容器中最大数据的数量 cout << "a.max_size() = " << a.max_size() << endl; return 0;}
2、【 STL】栈:
stack栈的常用操作函数:
top()
push()
pop()
size()
empty()
#include
//可以使用list或vector作为栈的容器,默认是使用deque的。
stack<int, list> a;
stack<int, vector> b;
printf("%d “, a.top());
//取栈项数据
a. push(3);
//将3这个元素入栈a
b. push(2);
//将2这个元素入栈b
a. pop();
//将栈顶元素出栈
//栈的大小printf(”%d %d\n", a.size(), b.size());
if(a.empty())return 1;
// 判断栈是否为空
3、【C++ 与 STL】映射:
map
map提供了“[]”运算符,使得map可以像数组一样使用所以map也称为“关联数组”map就是从键(key)到值(value)的映射。
例如可以用一个map<string, int> month_name 来表示“月份名字到月份编号”的映射然后用month_name[“July”] = 7 这样的方式来赋值
map的基本操作函数
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count(elem) 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
例题:反片语输入一些单词,找出所有满足如下条件的单词:该单词不能通过字母重排,得到输入文本中的另外一个单词。在判断是否满足条件时,字母不分大小写,但在输入时应保留输入中的大小写,按字典序进行排列(所有大写字母在小写字母的前面)
样例输入:ladder came tape soon leader acme RIDE lone Dreis peatScAlE orb eye Rides dealer NotE derail LaCeS drIednoel dire Disk mace Rob dries样例输出:DiskNotEderaildrIedeyeladdersoon
#include
#include
2)vector是一个模板类 所以使用时要用vector< int > a 或者 vector< double> b这样的方式来声明一个vector
vector< int>是一个类似于int a[]的整数数组,而vector< string>是一个类似于string a[]的字符串数组
clear()清空
resize()改变大小
push_back()在尾部添加元素
pop_back()在尾部删除元素
empty()测试是否为空
vector之间可以直接赋值或者作为函数的返回值
push_back()和pop_back()无需改变数组长度,自动会增加和减小数组长度增加长度后增加的元素值为0测试代码:
#include < iostream>
#include < vector>
using namespace std; int main() {
vector< int> a;
int t;
for (int i = 0; i < 10; i++) { cin >> t;
a.push_back(t); }
vector< int> b; b = a; cout << “print b: 直接赋值” << endl;
for (int i = 0; i < b.size(); i++) { cout << b[i] << " "; } cout << endl;
cout << "a.size() = " << a.size() << endl;
cout << “print1:” << endl; for (int i = 0; i < a.size(); i++) {
cout << a[i] << " "; } cout << endl;
a.resize(11);
cout << “a.size() = after resize(11) :” << a.size() << endl; cout << “print2 after resize(11):” << endl; for (int i = 0; i < a.size(); i++) { cout << a[i] << " "; }
cout << endl;
a.push_back(22);
cout << “print3 after push_back(22):” << endl;
for (int i = 0; i < a.size(); i++) {
cout << a[i] << " "; } cout << endl; a.pop_back();
cout << “a.size() = after pop_back() :” << a.size() << endl; cout << “print4 after pop_back():” << endl;
for (int i = 0; i < a.size(); i++) { cout << a[i] << " ";
} cout << endl;
cout << “a.empty()?:” << a.empty() << endl; a.clear();
cout << “a.size() = after a.clear() :” << a.size() << endl; cout << “print5 after a.clear():” << endl;
for (int i = 0; i < a.size(); i++) {
cout << a[i] << " "; }
cout << endl;
return 0;}
STL中vector的方法:
c.assign(beg,end) 将(beg; end)区间中的数据赋值给c。
c.assign(n,elem) 将n个elem的拷贝赋值给c
c. at(idx) 传回索引idx所指的数据,如果idx越界,抛出out_of_range。c.back() 传回最后一个数据,不检查这个数据是否存在。c.begin() 传回迭代器中的第一个数据地址。
c.capacity() 返回容器中数据个数。
c.clear() 移除容器中所有数据。
c.empty() 判断容器是否为空。
c.end() // 指向迭代器中末端元素的下一个,指向一个不存在元素。
c.erase(pos) // 删除pos位置的数据,传回下一个数据的位置。
c.erase(beg,end) 删除[beg,end)区间的数据,传回下一个数据的位置。
c.front() 传回第一个数据。
get_allocator 使用构造函数返回一个拷贝。
c.insert(pos,elem) // 在pos位置插入一个elem拷贝,传回新数据位置
c.insert(pos,n,elem) // 在pos位置插入n个elem数据,无返回值
c.insert(pos,beg,end) // 在pos位置插入在[beg,end)区间的数据。无返回值
c.max_size() 返回容器中最大数据的数量。
c.pop_back() 删除最后一个数据。
c.push_back(elem) 在尾部加入一个数据。
c.rbegin() 传回一个逆向队列的第一个数据。
c.rend() 传回一个逆向队列的最后一个数据的下一个位置。
c.resize(num) 重新指定队列的长度。
c.reserve() 保留适当的容量。
c.size() 返回容器中实际数据的个数。
c1.swap(c2) // 将c1和c2元素互换
十五、C++:string类中size()和length()的区别size() 一般用作返回容器大小的方法length() 一般用作返回一个序列的长度但是无论用size还是length,返回的结果都是一样的。
十六、string转int/float/double、int/float/double转string、转字符串数组的方法:stoi、stringstream、scanf、to_string、
sprintfhttps://www.cnblogs.com/luxiaoxun/archive/2012/08/03/2621803.html一、string转化为数字 1.使用stoi#include #include using namespace std;int main() { string str = “123”; int a = stoi(str); cout << a; str = “123.44”; double b = stod(str); cout << b; return 0;}/stoi如果是非法输入:1.会自动截取最前面的数字,直到遇到不是数字为止 (所以说如果是浮点型,会截取前面的整数部分)2.如果最前面不是数字,会运行时发生错误/ /* stod如果是非法输入: 1.会自动截取最前面的浮点数,直到遇到不满足浮点数为止 (所以说如果是浮点型,会截取前面的整数部分) 2.如果最前面不是数字或者小数点,会运行时发生错误 3.如果最前面是小数点,会自动转化后在前面补0 / /相应的还有:stof(string to float)stold(string to long double)stol(string to long)stoll(string to long long)stoul(string to unsigned long)stoull(string to unsigned long long)/ 2.使用stringstream#include #include using namespace std;int main() { string str = “1234”; stringstream stream; stream << str; int a; stream >> a; cout << a; return 0;}/如果转int是非法输入:1.会自动截取最前面的数字,直到遇到不是数字为止 (所以说如果是浮点型,会截取前面的整数部分)2.如果最前面不是数字,会转化为整数0/ / 如果转double是非法输入: 1.会自动截取最前面的浮点数,直到遇到不满足浮点数条件为止 2.如果最前面不是数字或者小数点,会转化为整数0 3.如果最前面是小数点,会转化为浮点数后在前面自动补0 */ /其他数字类型也可以转化/ 注意:sscanf、sprintf、atoi 操作对象为 字符数组(char c[]) 3.如果使用的不是string类,而是字符数组char c[] ①使用 sscanf#include #include using namespace std;int main() { char c[50] = “123”; int a; sscanf(c, “%d”, &a); // 不要忘记 “&” int b = 567; sprintf(c, “%d”, b); cout << a << endl << c; return 0;} /sscanf将字符数组转换为数字,输入到数字变量中sprintf将数字转换为字符数组,输出到字符数组变量中/ ②使用 atoi / atol / atoll#include #include using namespace std;int main() { char c[50] = “123”; int a = atoi©; cout << a; return 0;}二、数字转化为string 1.使用to_string#include #include using namespace std;int main() { int a = 123; string s = to_string(a); cout << s; return 0;} 2.使用stringstream#include #include using namespace std;int main() { stringstream stream; string str; int a = 123; stream << a; stream >> str; cout << str; return 0;}3.如果是字符数组(使用sprintf)#include #include using namespace std;int main() { char c[50] = “123”; int a; sscanf(c, “%d”, &a); // 不要忘记 “&” int b = 567; sprintf(c, “%d”, b); cout << a << endl << c; return 0;} /sscanf将字符数组转换为数字,输入到数字变量中sprintf将数字转换为字符数组,输出到字符数组变量中/
十七、【C++】fill函数
,fill与memset函数的区别fill与memset函数的区别~ memset函数 按照字节填充某字符在头文件里面 fill函数 按照单元赋值,将一个区间的元素都赋同一个值在头文件里面 因为memset函数按照字节填充,所以一般memset只能用来填充char型数组,(因为只有char型占一个字节)如果填充int型数组,除了0和-1,其他的不能。因为只有00000000 = 0,-1同理,如果我们把每一位都填充“1”,会导致变成填充入“11111111” 而fill函数可以赋值任何,而且使用方法特别简便: fill(arr, arr + n, 要填入的内容);例如: #include #include using namespace std;int main() { int arr[10]; fill(arr, arr + 10, 2); return 0;}12345678 vector也可以: #include #include #include using namespace std;int main(){ vector v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; fill(v.begin(), v.end(), -1); return 0;} 123456789 而memset的使用方法是: #include #include using namespace std;int main(){ int a[20]; memset(a, 0, sizeof a); return 0;
十八、cin.getline()、getline()、gets()、cin.get(),getchar()的区别
include string str1;char str2[100];cin >> str1;cin >> str2;//cin以空格和回车为结束符 char ch;cin.get(ch);//用来接收一个字符 char str[20];cin.get(str, 20);//接收一行字符串,可以接收空格 char str[20];cin.getline(str, 20);//接收一行字符串,可以接收空格cin.getline(str, 20, ‘#’);//接收一行字符串,可以接收空格,判断直到遇到’#'为止#include string s;getline(cin, s);//接收一行字符串//getline()和cin.getline()很类似,cin.getline()属于istream流,需要包含头文件//而getline()属于string流,需要包含头文件,是不一样的两个函数 char str[20];gets(str);//接收一行字符串到字符数组里面//gets使用的时候编译器可能会产生警告:warning: this program uses gets(), which is unsafe. 所以建议使用cin.getline() char ch;ch = getchar();//不能写成getchar(ch);