C++标准库使用

C++标准库使用

========================

测试了一些标准库提供的数据结构和函数等

值得一提的是那个自动推导auto用着非常舒服,可自动推导容器内的变量类型、函数的返回值类型等。
模板就不用说了,一行胜百行。需要大量重复的工作,还是建议用模板,模板的效率我还没时间去测试,不过不管怎么样,模板真方便。

1
2
3
4
5
6
template <typename T>
auto printData(const T& v){
for (auto i: v) {
cout<<i<<" ";
}
}

以下是.hpp文件和.cpp文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//
// test.hpp
// Code
//
// Created by 张赛东 on 2022/1/6.
//

#ifndef test_hpp
#define test_hpp

#include "stdc++.hpp"

using namespace std;
using gg = long long;

class Test {
int testThings;
public:
int func();
int func2();
};
#endif /* test_hpp */

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
//
// test.cpp
// Code
//
// Created by 张赛东 on 2022/1/6.
//

#include "test.hpp"

bool cmp(gg a, gg b) { return a<b; }

struct Compare {
// gg score;
// Compare(gg s):score(s){}
bool operator() (const gg& s1, const gg& s2)const {
return s1 < s2;
}
};

template <typename T>
auto printData(const T& v){//可能改变的话,就需要用引用&, 引用可被修改,值类型固定
for (auto i: v) {
cout<<i<<" ";
}
}

auto lowerBound1(vector<gg>& v, gg left, gg right, gg x, gg a) {
while(left<right){
gg mid = (left+right)/2;
if(v[mid]>x)
right=mid;
else
left=mid+1;
}
return left>right or v[left]>x?left:a;
}

int Test::func(){
vector<gg>v={2,1,4,3,6,5,8,10,5,3};
//sort(v.begin(),v.end());
sort(v.rbegin(),v.rend());
cout<<"V:\n";
//cout<<&v<<"\n";
// for (gg i: v) {
// cout<<i<<" ";
// }
printData(v);

reverse(v.begin()+4, v.begin()+6);//转置了第5(4+1)、6(5+1)个位置,6是开区间所在
cout<<"\n\n";
printData(v);

sort(v.begin(), v.end());//必须先排序,才能用unique去重,因为unique只看相邻的元素。
cout<<"This is v";
printData(v);
//auto it = unique(v.begin(), v.end());
vector<gg>::iterator it = unique(v.begin(), v.end());
v.erase(it, v.end());
cout<<"\n\n";
printData(v);

cout<<"\n\n";
auto it2 = remove(v.begin(), v.end(), 8);
v.erase(it2,v.end());
printData(v);

reverse(v.begin(), v.end());
partial_sort(v.begin(), v.begin()+4, v.end());
cout<<"\n\n";
printData(v);

reverse(v.begin(), v.end());
v.insert(v.begin(),{20, 29, 88, 15, 65, 3, 8 ,9});
nth_element(v.begin(), v.begin()+6, v.end());//将第6小的数字放到v[6]的位置(即第七个位置)上去,且其前面的数字必小于它,其后面的数字必大于它。
cout<<"\n\nThis is v:";
printData(v);

cout<<"\n\nThis is v:";
//任何二分查找算法都必须排序,没有顺序,还何谈二分。
sort(v.begin(), v.end()-1);
printData(v);
cout<< "\n";
//用v.end()-1比较好,因为v.end()它背后其实也还是有数字的,如:140704480081848,如果你查的数大于所有元素,那么此时会显示v.end()背后的值。
//当要读取值时,考虑v.end()-1,其他时候没必要。
cout<<*v.begin()<<" "<<*(v.end()-1)<<" "<<*v.end()<<" "<<*v.rbegin()<<"\n";
//输出第一个大于等于该数的值
cout<< *lower_bound(v.begin(), v.end()-1, 140704480081848)<< " " << *lower_bound(v.begin(), v.end()-1, 65)
//输出第一个大于该数的值
<<"\n"<< *upper_bound(v.begin(), v.end()-1, 9)<< " " << *upper_bound(v.begin(), v.end()-1, 65, cmp);

//输出第一个大于等于该数的值所在位置索引。
cout<<"\n\n";
cout<<"Position:"<<lowerBound1(v, 0, v.size()-1, 9, -1)<<" "<<lowerBound1(v, 0, v.size()-1, 65, -1);

//将序列调整为大根堆,即大顶堆。
make_heap(v.begin(), v.end());
cout<<"\n\n";
printData(v);

//将大根堆序列调整为升序,即堆排序。
sort_heap(v.begin(), v.end());
cout<<"\n\n";
printData(v);


sort(v.begin(), v.end(), greater<gg>());
//如序列已是最大的排列,将序列重排为最小的排列
next_permutation(v.begin(), v.end());
cout<<"\n\n";
printData(v);

sort(v.begin(), v.end(), greater<gg>());
cout<<"\n\n"<<*v.data();
cout<<"\n\nMax:"<<*max_element(v.begin(), v.end());
cout<<"\n\nMin:"<<*min_element(v.begin(), v.end());
//取值型的最好用v.end()-1。
cout<<"\n\nthe Max:"<<*minmax(v.begin(), v.end()-1).first<<"\n\nthe Min:"<<*minmax(v.begin(), v.end()-1).second;

cout<<"\n\nthe sum:";
//0表示初始值
cout<<accumulate(v.begin(), v.end(), 0)<<" "<<accumulate(v.begin(), v.end(), 100);


gg v2[100] = {6, 3, 4, 9, 2, 7, 8, 10, 3, 1, 2, 8, 7, 33, 58, 4, 6, 3, 4, 9, 2, 7, 8, 10, 3, 1, 2, 8, 7, 33, 51, 4,6, 3, 4, 9, 2, 7, 8, 10, 3, 1, 2, 8, 7, 33, 57, 4, 6, 3, 4, 9, 2, 7, 8, 10, 3, 1, 2, 8, 7, 33, 56, 4};
//sort(v2,v2+5);
//sort(v2, v2+3);
sort(v2, v2+10, greater<gg>());//10是开区间所在,故排序了第1(0+1)、……10(9+1)个位置。
sort(v2+10, v2+20, less<gg>());
sort(v2+20, v2+30, cmp);
sort(v2+30, v2+40, Compare());
sort(v2+40, v2+50, [](gg& a,gg& b){return a>b;});
partition(v2,v2+100, [](gg a){ return a!=3 && a!=7; });//符合条件的放到序列前方,不符合的放到序列后方

cout<<"\nV2:\n";
int times = 0;
for(gg i:v2) {
++times;
cout<<i<<" ";
if(times%10 == 0)
cout<<"\n";
}
cout<<"\n\n";
printData(v2);

cout<<"\nV3:\n";
char v3[20] = {'e','c','b','a','d','g','f','h','j','f','f'};//后面的默认为' ',即空字符。
sort(v3, v3+20);
cout<<"\n\n";
printData(v3);
//如序列已经是最小序列,则重排为最大序列
prev_permutation(v3, v3+20);
cout<<"\n\n";
printData(v3);

//将'u'赋值给指定位置元素,递增后的值赋值给下一个元素
iota(v3+10, v3+20, 'u');
cout<<"\n\n";
printData(v3);

int v4[] = {3,2,1};
int v5[] = {2,1,3};
//向量内积
cout<<"\n\n"<<inner_product(v4, v4+3, v5, 0);

int v6[] = {0,1,2,3,4,5,6,7,8,9};
//这里多输出个地址不知道怎么回事
cout<<"\n\n"<<partial_sum(v6, v6+10, v6);
printData(v6);

vector<int> v7 = {0,1,2,3,4,5,6,7,8,9};
cout<<"\n\n";
//前缀和,即前n项和。
partial_sum(v7.begin(), v7.end(), v7.begin());
printData(v7);

//前缀和的逆向操作。
cout<<"\n\n";
adjacent_difference(v7.begin(), v7.end(), v7.begin());
printData(v7);

cout<<"\n\n";
bitset<8> b(257);
cout<<b<<" "<<b.flip()<<" "<<b.to_ulong()<<" "<<b.to_ullong()<<"\n";

bitset<16> b2(257);//整数的二进制表示
cout<<b2<<" "<<b2.flip()<<" "<<b2.to_ulong()<<" "<<b2.to_ullong()<<"\n"
<<(b2<<2)<<" "<<(b2>>1)<<"\n"<<(b2<<=2)<<" "<<(b2>>=1)<<"\n"
<<b2<<" "<<~b2<<" "<< (b2&=255) <<'\n'
<<(b2^=255)<<" "<<(b2|=255)<<" "<<(b2^=255) <<'\n'
<<b2[12]<<" "<<b2.count()<<" "<<~b2<<" "<<(b2|=255)<<" "<<b2.count()<<'\n'//count: b2中true即1的位数
<<b2.reset()<<" "<<b2.all()<<" "<<b2.any()<<" "<<b2.none()<<'\n';

cout<<to_string(1000)<<" "<<stoi("1111")<<" "<<stod("10.78")<<" "<<stof("11.766")<<'\n';
cout<<showpos<<20<<" "<<100<<" "<<20-50<<'\n';//展示正负号
cout<<to_string(1000)<<" "<<stoi("1111")<<" "<<stod("10.78")<<" "<<stof("11.766")<<'\n';
cout<<noshowpos<<to_string(1000)<<" "<<stoi("1111")<<" "<<stod("10.78")<<" "<<stof("11.766")
<<" "<<stol("23453")<<" "<<stoll("1043791749713284")<<'\n';

string str = "00001234";
str.erase(0, str.find_first_not_of('0'));//第一个不是0的数字。
cout<<str<<'\n';
cout<<'8' - '0'<<'\n';

string str2 = "63433";
for (char c: str2) {
c-= '2';
}
cout<<str2<<'\n';

cout<<fixed<<setprecision(10)<<1e5<<" "<<200e5<<" "<<(double)3e-8<<'\n';//1乘以10的5次方

//并查集
vector<gg> ufs(1e2);
iota(ufs.begin(), ufs.end(), 0);//赋值函数
printData(ufs);
cout<<"\n";

return 0;
}

int Test::func2(){
ios::sync_with_stdio(false);
cin.tie(0);
string s;
getline(cin, s);
cout<<s;
return 0;
}