语言/CPP {系统的东西}
语言/CPP {系统的东西}
系统的宏/常量
__DATE__: "Dec 19 2023"
__TIME__: "17:55:19"
;
__TIMESTAMP__: "Tue Dec 19 17:55:11 2023"
;
__cplusplus: 201703
: CPP语言的版本;
特殊语法
R"()"
string s = "a\nb";
string会进行转义, 即这字符串的长度会是3
而不是4
, 也就是 \n
是一个字符;
假如你就是想要一个字符串 长度为4
内容为a \ n b
, 那么麻烦一点 你可以手动的s[1] = '\\'
;
有一个系统的工具 R"()"
(他很特别, 既不是函数 也不是宏, 反正是个特殊的语法), 你通过string s = R"(xxx)";
那么xxx
的内容 不会转义, 你写的是R"(a\nb)"
, 那么 他就是4个字符;
@DELI;
系统的类/结构体
is_literal_type
literal
字面类型, 即他就是一个值/数据 , 没有函数 不是通常意义上的对象;
字面类型有: bool, char, int, long long, double, T *, T &, T &&
;
string
vector
@DELI;
erase
iterator erase( iterator _a);
iterator erase( iterator _beg, iterator _end);
erase
会调用对象的析构函数 释放内存, 但不会改变vector.capacity()
;
vector A{1, 2, 3, 4, 5};
auto iter = A.erase( A.begin() + 1); // 删除`2`
//>< 此时A为`1,3,4,5`, `iter`会指向被删元素的下个元素 即`3`;
auto iter = A.erase( A.begin() + 1, A.begin() + 3); // 删除`2,3`
//>< 此时A为`1,4,5`, `iter`会指向被删元素的下个元素 即`4`;
@DELI;
resize
;
void resize(size_type __new_size);
void resize( _n){
if( _n > .size()){
if( _n <= .capacity()){
.size() = _n;
}
else{
.capacity() = _n;
}
}
else{
.size() = _n;
//< Notice, `capacity()` is not changed;
}
}
@DELI;
emplace_back
;
void emplace_back(_Args&&... __args);
.
注意他的函数参数 完全不同于push_back
, 他用的可变长函数参数, 即不管你这个vector里的元素是什么, 他永远都形如emplace_back( a, b, c, d, ...)
这个样子;
.
vector< T> A
, 当你调用A.emplace_back( a,b,c)
时 等价于往A里添加了一个 T(a,b,c)
的对象 (前提是T有形如这样的构造函数);
建议:
当元素是个int, string, ...
比较单一, 就使用push_back
;
否则, 比如元素是pair, tuple
, 就使用emplace_back
;
vector< pair< int, int> > v;
v.push_back( {1,2}); // @Mark_0
v.push_back( pair<int,int>(1,2)); // @Mark_1
v.emplace_back( 1, 2); // @Mark_2
@Mark_0, @Mark_1
are the same, it causes two operations:
0 Constructor-Function (i.e., produce a Temporary-Object);
1 Copy/Move-Constructor-Function (the requirement of push_back
);
@Mark_2
has just one-operation: Constructor-Function (removed the second-step above);
If you wanna add a Empty-Object to vector< T> v
, you can use v.emplace_back( )
;
@DELI;
is_same
判断两个类型是否相同;
bool ret = is_same< int, int &>::value;
@DELI;
remove_reference
, remove_reference_t
;
去除掉一个类型的引用 (不管是左值引用T&
还是右值引用T&&
), 最终都会变成T
;
remove_reference< int &>::type a = 123;
一定一定要注意, 他是一个类! 你非常容易把后面的::type
给忘掉
.
因此, 专门有个remove_reference_t
, 你可以用remove_reference_t< int &> a = 123;
系统的函数
unique
使用unique
对数组去重的前提是: 数组已经排好序了 (升序降序都可以);
.
也就是, 在调用unique
之前, 必须要有个sort
函数的执行;
A = {1, 1, 2, 2, 3, 3};
B = {3, 3, 2, 2, 1, 1};
auto iter = unique( A.begin(), A.end());
//>< 此时A为{1,2,3, 2,3,3}, `iter - A.begin() = 3`;
auto iter = unique( B.begin(), B.end());
//>< 此时A为{3,2,1, 2,1,1}, `iter - B.begin() = 3`;
假如有
k
k
k个不同的元素, 那么 这
k
k
k个不同元素 一定会在数组的开头
k
k
k的位置, 而具体后面的元素是什么 这是未知的, 即unique
不仅仅是会修改元素的位置, 还可能修改元素的值;
accumulate
Source-Code
template<typename _InputIterator, typename _Tp>
_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init){
for (; __first != __last; ++__first)
__init = __init + *__first;
return __init;
}
Example
set< int> S;
auto sum = accumulate( S.begin(), S.end(), 0LL);
count
, count_if
Source-Code
int count( Iter _beg, Iter _end, T _tar){
int ans = 0;
for( Iter i = _beg; i != _end; ++i){
if( *i == _tar){ ++ ans;}
}
return ans;
}
int count_if( Iter _beg, Iter _end, Function _check){
int ans = 0;
for( Iter i = _beg; i != _end; ++i){
if( _check( *i)){ ++ ans;}
}
return ans;
}
Example
vector< int> A{ 1,2,3};
`count( A.begin(), A.end(), 3)` equals `1`;
`count_if( A.begin(), A.end(), []( auto _a)->bool{ return _a != 3;})` equals `2`;
find
, find_if
Source-Code
Iter find( Iter _beg, Iter _end, T _tar){
for( Iter i = _beg; i != _end; ++i){
if( *i == _tar){ return i;}
}
return _end;
}
Iter find_if( Iter _beg, Iter _end, Function _check){
for( Iter i = _beg; i != _end; ++i){
if( _check( *i)){ return i;}
}
return _end;
}
Example
vector< int> A{ 1, 1, 2, 2, 3, 3};
`find( A.begin(), A.end(), 3)` equals `A.begin() + 4`;
`find( A.begin(), A.begin() + 4, -1)` equals `A.begin() + 4`;
nth_element
Source-Code \text{ Source-Code} Source-Code
nth_element(_RAIter, _RAIter, _RAIter);
nth_element(_RAIter, _RAIter, _RAIter, _Compare);
.
nth_element( ?, ?, ?)
equals to nth_element( ?, ?, ?, less<>())
;
@Delimiter
Function \text{ Function} Function
nth_element( v.begin(), v.begin() + k, v.end());
.
将前
k
k
k小的元素, 放到数组的开头; 比如[4,6,5,3,2,1]
如果
k
=
3
k=3
k=3 则最终数组可能为[2,1,3, 5,4,6]
次序不唯一, 但前
3
3
3小的元素 肯定在最开头;
vector< T> v{ ...};
n = v.size();
k = [1, n-1];
@Define( S: the set of the smallest `k` elements in `v`);
nth_element( v.begin(), v.begin() + k, v.end());
. Now, `v[0,1,...,k-1]` would be `S` (the order of `v[0,1,...,k-1]` maybe not increasing);
@Delimiter
vector< int> v{ 6, 4, 3, 5, 1, 2};
nth_element( v.begin(), v.begin() + 3, v.end());
. Which is equivalent to `nth_element( v.begin(), v.begin() + 3, v.end(), less<>())`;
. Now, `v = [2,1,3, 5,4,6]`;
nth_element( v.begin(), v.begin() + 3, v.end(), greater<>());
. Now, `v = [4,6,5, 2,3,1]`;