语言/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]`;