基础

技巧

  • 无内存申请交换
1

STL

string

进制转换

atoi(char) 头文件 #include
atoi(line.c_str())记住要转为C风格字符串
char* itoa (int value,char*string,int radix);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
using namespace std;
string reverse(string s, int radix_1, int radix_2){//将radix1进制数转换成radix2进制数
char * stop=NULL;
long a = strtol(s.c_str(), &stop,radix_1);
char buff[20];
memset(buff,0,sizeof(char)*20);
ltoa(a, buff, radix_2);
return string(buff);
}

int main()
{
string s="0xAA";
cout<<reverse(s, 16,10)<<endl;
cout<<reverse("AA", 16,10)<<endl;
cout<<"Hello World"<<endl;
return 0;
}

基本操作

C++ string详解,C++字符串详解
C++ string的常用操作
C++string类的常用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
s.empty()
s.size()
string& insert (size_t pos, const string& str);
string& erase (size_t pos = 0, size_t len = npos);
char &at(int n);

isnt find(const char *s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置
//子字符串

string &replace(int p0, int n0,const char *s);//删除从p0开始的n0个字符,然后在p0处插入串s
string &replace(int p0, int n0,const char *s, int n);//删除p0开始的n0个字符,然后在p0处插入
string &replace(int p0, int n0,int n, char c);//删除p0开始的n0个字符,然后在p0处插入n个字符c

读写一行字符串:getline(cin, line)

  • 去除空格trim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
string& trim(string &s) 
{
if (s.empty())
{
return s;
}
s.erase(0,s.find_first_not_of(" "));
s.erase(s.find_last_not_of(" ") + 1);
int a=s.find(" ");
if(a<0) return s;
int b=s.find_first_not_of(" ", a);
while(b>0){
s.erase(s.begin()+a+1,s.begin()+b);
a=s.find(" ");
if(a<0) break;
b=s.find_first_not_of(" ",a);
}
return s;
}

处理string中的字符

头文件:#include <cctype>

是否是字符数字: isalnum(c)
是否是字母:isalpha(c)
是否是小写字母:islower(c)
是否是大写字母:isupper(c)
是否是数字:isdigit(c)
是否是16进制数字:isxdigit(c)
转小写字母:tolower(c)
转大写字母:toupper(c)
是否是标点符号:ispunct(c)

Demo code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
#include <cctype>
using namespace std;

int main()
{
string input;
getline(cin,input);
cout<<"sentence:"+input<<endl;
string s="Hello World!!!";
int cnt_punct=0;
for(auto c :s)
{
if(ispunct(c))
{
++cnt_punct;
}
}
cout<<cnt_punct<<endl;
return 0;
}

string.split()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
#include <string>
#include <vector>
using namespace std;


void Stringsplit(const string& str, const char split, vector<string>& res)
{
if (str == "") return;
//在字符串末尾也加入分隔符,方便截取最后一段
string strs = str + split;
size_t pos = strs.find(split);

// 若找不到内容则字符串搜索函数返回 npos
while (pos != strs.npos)
{
string temp = strs.substr(0, pos);
res.push_back(temp);
//去掉已分割的字符串,在剩下的字符串中进行分割
strs = strs.substr(pos + 1, strs.size());
pos = strs.find(split);
}
}

// 使用字符串分割
void Stringsplit(const string& str, const string& splits, vector<string>& res)
{
if (str == "") return;
//在字符串末尾也加入分隔符,方便截取最后一段
string strs = str + splits;
size_t pos = strs.find(splits);
int step = splits.size();

// 若找不到内容则字符串搜索函数返回 npos
while (pos != strs.npos)
{
string temp = strs.substr(0, pos);
res.push_back(temp);
//去掉已分割的字符串,在剩下的字符串中进行分割
strs = strs.substr(pos + step, strs.size());
pos = strs.find(splits);
}
}


int main()
{
vector<string> strList;
string str("This-is-a-test");
Stringsplit(str, '-', strList);
for (auto s : strList)
cout << s << " ";
cout << endl;

vector<string> strList2;
string str2("This%20is%20a%20test");
Stringsplit(str2, "%20", strList2);
for (auto s : strList2)
cout << s << " ";
cout << endl;
return 0;
}

List 双向链表

C++ list(STL list)容器完全攻略(超级详细)

array

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <array>
using namespace std;
int main()
{
array<int, 4> values{};
//初始化 values 容器为 {0,1,2,3}
for (int i = 0; i < values.size(); i++) {
values.at(i) = i;
}
//使用 get() 重载函数输出指定位置元素
cout << get<3>(values) << endl;
//如果容器不为空,则输出容器中所有的元素
if (!values.empty()) {
for (auto val = values.begin(); val < values.end(); val++) {
cout << *val << " ";
}
}
}

C++ array(STL array)容器用法详解

vector

C++ STL vector容器详解

  • 尾部添加元素:push_back()
  • 插入:insert(this.end(), new.begin(),new.end())
  • pop_back() 移出序列尾部的元素。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <vector>
using namespace std;

int main() {
std::vector<int> primes {2, 3, 5, 7, 11, 13, 17, 19};
vector<int> vals,sub;
vals.push_back(1);
vals.push_back(1);
vals.push_back(1);
sub.push_back(2);
sub.push_back(2);
vals.insert(vals.begin()+1,sub.begin(), sub.end());
for(auto a:vals) cout<<a<<" ";

return 0;
}

queue

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 &other_q):将当前 queue 中的元素和参数 queue 中的元素交换。它们需要包含相同类型的元素。也可以调用全局函数模板 swap() 来完成同样的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>
#include <queue>
#include <deque>
using namespace std;

int main()
{
deque<double> values {1.5, 2.5, 3.5, 4.5};
queue<double> numbers(values);
for(int i=0;i<5;++i)
{
numbers.push(i); //队尾添加元素
}

while (!numbers.empty())
{
cout <<numbers.front() << " "; // 查询队首
numbers.pop(); // 弹出队首
}
cout<<endl;
return 0;
}

C++ queue(STL queue)用法详

priority_queue

STL | priority_queue(优先队列)基本用法

  • Container:必须是用数组实现的容器,比如 vector, deque,但不能用 list。STL里面默认用的是 vector。
  • Compare:比较方式默认用使用less,operator <(小于号)。
  • 所以如果你把后面俩个参数缺省的话,优先队列就是大顶堆,队头元素最大。

C++ priority_queue(优先队列)使用

1
2
3
4
5
empty()  //如果优先队列为空,则返回真 
pop() //删除第一个元素
push() //插入一个元素
size() //返回优先队列中拥有的元素的个数
top() //返回优先队列中有最高优先级的元素

三种自定义比较函数方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//一、lamda表达式
priority_queue<ListNode*, vector<ListNode*>, function<bool(ListNode*, ListNode*)>> pq(
[] (ListNode* a, ListNode* b) { return a->val > b->val; });

// 二、重载 < 运算符,实现大顶堆
bool operator<(ListNode* a, ListNode* b)
{
return a.val<b.val;
}
priority_queue<ListNode*> pq;
priority_queue<ListNode*, vector<ListNode*>, less<ListNode*> > pq;

// 三、仿函数,实现大顶堆
struct cmp
{
bool operator() (ListNode* a,ListNode* b )
{
return a->x<b->x;
}
};
priority_queue<ListNode*,vector<ListNode*>,cmp>que;

deque 双边队列

C++ STL deque容器(详解版)

stack

下面是 stack 容器可以提供的一套完整操作:

  • top():返回一个栈顶元素的引用,类型为 T&。如果栈为空,返回值未定义。

  • push(const T& obj):可以将对象副本压入栈顶。这是通过调用底层容器的 push_back() 函数完成的。

  • push(T&& obj):以移动对象的方式将对象压入栈顶。这是通过调用底层容器的有右值引用参数的 push_back() 函数完成的。

  • pop():弹出栈顶元素。

  • size():返回栈中元素的个数。

  • empty():在栈中没有元素的情况下返回 true。

  • emplace():用传入的参数调用构造函数,在栈顶生成对象。

  • swap(stack & other_stack):将当前栈中的元素和参数中的元素交换。参数所包含元素的类型必须和当前栈的相同。对于 stack 对象有一个特例化的全局函数 swap() 可以使用。

Demo code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
#include <stack>
#include <list>
using namespace std;

int main()
{
list<string> ls{"java","python","go","c++"};
stack<string,list<string>> st(ls);
st.emplace("ruby");
while(!st.empty())
{
cout<<st.top()<<endl;
st.pop();
}
return 0;

C++ stack(STL stack)用法详解

map

C++ STL map容器详解
底层用的红黑树,会自动按照key排序,如果不需要排序,建议使用unordered_map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
#include <map>
using namespace std;

int main()
{
map<string, int> myMap{ {"c",10},{"d",20} };
map<string, int>newMap(++myMap.begin(), myMap.end());
myMap.insert(make_pair("java",30));
myMap.emplace(pair<string, int>("go", 5));//在当前 map 容器中的指定位置处构造新键值对。其效果和插入键值对一样,但效率更高。
myMap.emplace(make_pair("C++",40));
auto itera = myMap.find("java");
if(itera!= myMap.end()){
cout<<itera->second;
}
for(auto p : myMap)
{
cout<<p.first<<"\t"<<p.second<<endl;
}
return 0;
}

multimap

C++ STL multimap容器用法完全攻略(超详细)

unordered_map

C++ STL unordered_map容器用法详解

set

C++ STL set容器完全攻略(超级详细)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>
#include <set>
using namespace std;

int main()
{
set<string> sets{"c++","java","go"};
sets.insert("python");
for(auto a : sets)
{
cout<<a<<endl;
}
sets.erase();
return 0;
}
  • insert() 向 set 容器中插入元素。
  • erase() 删除 set 容器中存储的元素。
  • clear() 清空 set 容器中所有的元素,即令 set 容器的 size() 为 0。
  • count(val) 在当前 set 容器中,查找值为 val 的元素的个数,并返回。注意,由于 set 容器中各元素的值是唯一的,因此该函数的返回值最大为 1。

unordered_set

C++ STL unordered_set容器完全攻略

泛型算法

#include

1
swap(a,b)

reverse()

sort()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <string>
#include <array>
#include <algorithm>
using namespace std;
int main()
{
array<int,7> a{0,6,3,2,4,5,1};
array<int,4> b{2,7,5,3};

sort(a.begin(),a.end());
for(auto t:a)
cout<<t<<"\t";
cout<<endl;

sort(a.begin(),a.end(),[](int a, int b) -> bool { return a > b; });
for(auto t:a)
cout<<t<<"\t";
cout<<endl;

reverse(a.begin(),a.end());
for(auto t:a)
cout<<t<<"\t";
cout<<endl;

return 0;
}

C++ unique(STL unique)算法详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <array>
using namespace std;

int main()
{
// int a[] = {1,2,3,7,6,3,4};
array<int,7> a{1,2,3,7,6,3,4};
cout<<sizeof(a)/sizeof(int)<<endl;
sort(begin(a), end(a));
for(auto t:a)
{
cout<<t<<" ";
}
cout<<endl;
auto end_iter = unique(begin(a), end(a));
copy(begin(a), end(a), ostream_iterator<int>{cout, " "});
cout<<endl;
for(auto t:a)
{
cout<<t<<" ";
}
return 0;
}

常用算法

Lamda

C++——Lambda函数
C++11 lambda表达式精讲

C++11 lambda表达式

min_element()

partition()

1
partition(nums.begin(), nums.end(), [](const int n){ return n&1; });

STL算法

sort

它有三个参数sort(begin, end, cmp),
其中begin为指向待sort()的数组的第一个元素的指针,
end为指向待sort()的数组的最后一个元素的下一个位置的指针,
cmp参数为排序准则,cmp参数可以不写,如果不写的话,默认从小到大进行排序。如果我们想从大到小排序可以将cmp参数写为greater<int>()就是对int数组进行排序

注意:sort默认是由小到大排序,而priority_queue是默认大根堆,弹出顺序是从大到小。两者第三个参数都是排序规则,默认也都是less,但是参数类型不一样,sort()是less<int>()priority_queueless<int>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
#include<algorithm>
using namespace std;

// 自定义规则
bool cmp(int x,int y){
return x % 10 > y % 10;
}

int main(){
int num[10] = {6,5,9,1,2,8,7,3,4,0};
sort(num,num+10,greater<int>());
// sort(num,num+10, [](int a, int b){return a%10>b%10;});
for(int i=0;i<10;i++){
cout<<num[i]<<" ";
}//输出结果:9 8 7 6 5 4 3 2 1 0

return 0;

}

面试宝典

史上最全的C++面试宝典(合集)

C/C++面试宝典2020版(最新版)

待定

c++机试中的输入输出问题

HelloWorld

1
2
3
4
5
6
7
8
#include <iostream>
using namespace std;
int main()
{
cout<<"HelloWorld!"<<endl;
system("pause");
return 0;
}

输入输出

  • 多个输入,每行一个输入,无空格
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
using namespace std;
int main()
{
int n;
//c++写法
while(cin >> n){

}
//c语言写法
while(scanf("%d", &d) != EOF){

}
return 0;
}
  • 有空格
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
string input;
// Hello World!
while(getline(cin,input))
{
cout<<"sentence:"+input<<endl;
vector<string> strs;

}

cout<<"Hello World"<<endl;
return 0;
}

CFree

下载地址