undefined

链接的问题

https://latedev.wordpress.com/2014/04/22/common-c-error-messages-2-unresolved-reference/

https://latedev.wordpress.com/2011/07/08/the-gcc-command-line-part-1/

c/c++错误之 Undefined reference  未定义的问题

首先看一看链接器的作用。在构建c++程序的时候,几乎所有的程序都由多个c++源文件组成。使用c++编译器分别编译这些文件,以生成包含机器代码的目标文件(.o 或者 .obj 文件),每个目标文件对其他文件一无所知。所以,如果从另一个目标文件中存在的一个目标文件调用函数,则编译器将无法提供被调用函数的地址。

一旦生成了所有的目标文件,想要生成最终的可执行文件,那么链接器就会查看他们并计算出可执行文件中函数的最终地址是什么。然后他修补了编译器无法提供的地址。对于可能使用的任何库(.a 和 .lib 文件) ,他都执行相同的操作。最后,他将可执行文件写到磁盘。

链接器通常是与编译器分开的程序,例如:gcc 链接器成为 ld。传统上,链接器技术落后于编译器,主要是因为构建编译器比构建链接器通常更加有趣。并且链接程序不一定有权访问他们正在链接的目标文件的源代码。

查看更多

undefined

linux 系统调用及错误处理:https://blog.csdn.net/freecls/article/details/80369878

1
2
void perror(const char *msg);
此函数会打印出字符串msg紧跟与当前errno值对应的错误描述。
1
2
char *strerror(int errnum);
该函数会根据errnum错误号返回错误描述字符串,由于返回的字符串是静态分配的,这就意味着后续调用strerror()可能会覆盖之前的字符串,所以如果该错误描述后续还要用到,建议复制一个副本。

查看更多

undefined

二分查找

二分查找的时间复杂度:logn

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bool binary_sort(std::vector<int>& vec, int value) {
int left = 0;
int right = vec.size()-1;
while (left <= right) {
int mid = left + (right - left)/2;
if (value == vec[mid]) {
return true;
} else if (value > vec[mid]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return false;
}

注意循环条件为:left <= right 以及注意 left + right 越界的情况

一、条件

查看更多

undefined

分治算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def divide_conquer(problem, param1, param2, ...):
# recursion terminator
if problem is None:
print_result
return
# prepare data
data = prepare_data(problem)
subproblems = split_problem(problem, data)
# conquer subproblems
subresult1 = self.divide_conquer(subproblems[0], p1, ...)
subresult2 = self.divide_conquer(subproblems[1], p1, ...)
subresult3 = self.divide_conquer(subproblems[2], p1, ...)
...
# process and generate the final result
result = process_result(subresult1, subresult2, subresult3, ...)

# revert the current level states

回溯算法

undefined

前序、中序、后序的非递归算法

前序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void PreOrderIteration(TreeNode* root) {
if (root == nullptr) return;
std::stack<TreeNode*> st;
st.push(root);
while (!st.empty()) {
auto node = st.top();
std::cout << node->value << ' ';
st.pop();
if (node->right != nullptr) {
st.push(node->right);
}
if (node->left != nullptr) {
st.push(node->left);
}
}
}

中序

查看更多

undefined

一、哈希算法

哈希算法定义:将任意长度的二进制串映射为固定长度的二进制串,这个映射的规则就是哈希算法,而通过原始数据映射之后得到的二进制串就是哈希值。需要满足几点要求:

  1. 从哈希值不能反向推导出原始数据
  2. 对输入数据非常敏感,哪怕原始数据只修改了一个 bit,最后得到的哈希值也大不相同
  3. 哈希冲突的概率要很小,对于不同的原始数据,哈希值相同的概率非常小
查看更多

undefined

无向图、有向图、带权图

一、如何存储

1. 邻接矩阵

使用二维数组存储,如果有一条箭头从顶点 j 指向顶点 i 的边,我们就将 A[j][i]标记为 1。对于带权图,数组中就存储相应的权重。

  • 缺点:空间浪费,对于无向图,只需要上面或者下面一半空间就够了;而且像存储的是稀疏图(顶点很多,但每个顶点的边并不多),也很浪费空间

查看更多