提示:可以和大家分享最初成为创作者的初心
在一些实战项目中,会写一些不错的模块。
或者说碰到一些有意思的情况,会作为记录拿出来分享。
本人主要是算法竞赛与C++方面的学习。
在在校期间主要是算法为主,偶尔会记录一些学校课程中的内容。
工作后的学习就以技术为主了,虽然也会刷些算法,但是大都是吃老本算法相关文章也是越来越少了。
文章主要是作为我个人的记录,我也是希望能与他人交流的,但几乎没看到谁看了我的文章专门跑过来与我交流。
偶尔会看到后台一些朋友的提问,如果我看的即使的话,会回答一些。时间过太久一般就不答了。
提示:在创作的过程中都有哪些收获
我从不意我在CSDN上的粉丝量。
? 以前会关注一些访问量,但到了10w访问后就也不太在意了。
之前大概是创作第二年的时候,自己给自己定了一个10w的目标。但没有在理想时间内达到。
? 评论我一定会看,主要是想看看这篇文章对读者的真实反馈,点赞什么的就不会太在意。
? 正向反馈,或者说实际反馈几乎没有。毕竟写了这么多也没拿到一块钱。
? 当然当时和力扣leetcode签订创作者协议的时候,我将csdn的博客作为自己的一份能力证明表了出来,这应该算是我的一份正向推动吧。
没有。
但当然我也希望有,如果有同行愿意与我交流合作的话欢迎联系啊。
提示:当前创作和你的工作、学习是什么样的关系
算是一半吧。
不算有合同的创作。这种一块钱也拿不到的创作,完全取决于自身平时的学习和生活状况。
我完全可以一个月也不创作一篇,但是我目前还是会给自己限定自我约束。
确实精力非常有限。首先必须得腾出时间,那必然是下班后,或者假期期间了。
在平时学习的时候,会给自己做一些简单的记录,是真的简单的在比如手机代办事项上做一条标记。
然后偶尔,比如在睡前规划一下创作的计划。
最后说一下,个人为了更好的创作和工作学习,目前在时不时在使用番茄钟的方式进行做事。(比如在写本文时,我就是在用番茄钟(瞄了一眼时间,倒计时正好1分钟了,我又可以休息了😂))
提示:你过去写得最好的一段代码是什么? 请用代码块贴出来
在一道线段树题目中,因为数据量很大,所以需要动态开点。
本人还是喜欢使用指针的方式,但是有一道题内存卡的太恶心,必须得用数组估计法。
为了不想改动太大,我直接让指针指向数组的位置。这样只要写一个判断指针是否为空的地方处理即可。
并且在外部调用时,因为动态开点的方式不一样,导致接口不一样,因此直接再度在线段树类中封装了一层。
这就像适配器模式一样的,进行代码的隔离。
具体题目为:715. Range 模块
code:
AC-Code-715. Range 模块
// 手写递增分配器
template<typename Type, size_t N>
class TreeAllocator {
Type node[N];
size_t i = 0;
public:
Type* get() {
auto p = node + i;
i += 1;
new (p) Type{};
return p;
}
};
// 区间 true | false
// 区间统计
class SegmentTree {
private:
struct Node {
int val = 0;
int lazy = -1;
Node* left = nullptr;
Node* right = nullptr;
};
TreeAllocator<Node, 500010> alloc;
Node* root = nullptr;
const int n = 1e9 + 7;
public:
SegmentTree() {
root = alloc.get();
}
private:
/**
* 隔离底层实现核心
*/
void checkSon(Node* root) {
if (nullptr == root->left) {
root->left = alloc.get();
}
if (nullptr == root->right) {
root->right = alloc.get();
}
}
void pushUp(Node* root) {
root->val = root->left->val + root->right->val;
}
// 每次调用 pushDown 首先第一步检查左右子树
void pushDown(Node* root, int left, int right) {
checkSon(root);
if (root->lazy == -1) {
return;
}
// lazy 只有1|0 表示true|false
const int mid = left + (right - left) / 2;
const int leftLen = mid - left + 1;
const int rightLen = right - mid;
root->left->val = leftLen * root->lazy;
root->right->val = rightLen * root->lazy;
root->left->lazy = root->lazy;
root->right->lazy = root->lazy;
root->lazy = -1;
}
private:
// bool val
// true | false 的全覆盖
void update(Node* root, int left, int right, int from, int to, bool val) {
if (from > right || to < left) {
return;
}
if (from <= left && right <= to) {
root->val = val * (right - left + 1);
root->lazy = val;
return;
}
pushDown(root, left, right);
const int mid = left + (right - left) / 2;
update(root->left, left, mid, from, to, val);
update(root->right, mid + 1, right, from, to, val);
pushUp(root);
}
int query(Node* root, int left, int right, int from, int to) {
if (from > right || to < left) {
return 0;
}
if (from <= left && right <= to) {
return root->val;
}
pushDown(root, left, right);
const int mid = left + (right - left) / 2;
return query(root->left, left, mid, from, to) +
query(root->right, mid + 1, right, from, to);
}
public: // 再度为外部调用的接口
void add(int left, int right, int val) {
update(root, 1, n, left, right, val);
}
int ask(int left, int right) {
return query(root, 1, n, left, right);
}
};
class RangeModule {
SegmentTree tree;
public:
RangeModule() {
}
// RangeModule 的所有查询更新是 `left <= x < right`
// SegmentTree 的所有查询是 `[left, right]`
void addRange(int left, int right) {
tree.add(left, right - 1, true);
}
bool queryRange(int left, int right) {
// 查询区间为true的点数是否为区间长度
return tree.ask(left, right - 1) == (right - left);
}
void removeRange(int left, int right) {
tree.add(left, right - 1, false);
}
};
在一个表示多状态的情况下,比如有8个状态位标志。按照以往的方式是做8个int标记。但是这样的开销实在太大。
由于实际的场景中,只每个表示表示的0/1。因此从内存优化的角度出发,可以使用位域的方式。
并且根据协议的特点,使用一个联合体进行操作,便于数据的读取和赋值。最后基于C/C++的可以使用匿名union和struct的特点,形成了如下的数据结构与代码。
#include <cstdint>
#include <cstring>
struct StateBits {
union {
::std::uint8_t ALL;
struct {
::std::uint8_t b00_xstate : 1; // 00-x轴是否运动中
::std::uint8_t b01_ystate : 1; // 01-y轴是否运动中
::std::uint8_t b02_zstate : 1; // 02-z轴是否运动中
::std::uint8_t : 1; // [占位]
::std::uint8_t : 3; // [占位]
::std::uint8_t b07_isstatic : 1; // 07-是否是静止状态
};
} data;
StateBits() {
static_assert(sizeof(data) == sizeof(::std::uint8_t),
"The Bits Are Not Aligned");
::std::memset(this, 0, sizeof(*this));
}
};
#include <iostream>
int main() {
::std::cout << "sizeof(StateBits) = " << sizeof(StateBits) << ::std::endl;
// 外部获得的数据
::std::uint8_t state = 0b0000'0111;
StateBits sb;
// 直接映射赋值
sb.data.ALL = state;
if (sb.data.b07_isstatic) {
::std::cout << "is static" << ::std::endl;
} else {
::std::cout << "is not static" << ::std::endl;
}
}
提示:职业规划、创作规划等
老实说,现在事业一片渺茫。
有前辈愿意交流一下吗?
还是按照目前这个状态,个人还是蛮满意的。
算法文章和技术文章的,形式我也会慢慢形成自己的风格,当然目前已经有了一定的自己的风格了。
以后会考虑出视频的方式,这就脱离了文章的范畴了,这里不展开说了。