作为一个偏科严重的理工男,高中时期,我可以在数学和理综考试中拿到满分或者接近满分的成绩,但我也可以在语文和英语两门科目当中考出刚及格甚至不及格的成绩。因此,迷上写博客文章,以及出版一本 GRE 的练习册对我而言也算是很神奇的事情了。

阅读全文 »

数独是一种益智解谜游戏。初始状态,在 $9\times 9$ 的盘面上,零星分布着一些 1 – 9 的整数。规则要求玩家在初始状态的基础上,填入 1 – 9 的数字,使得 $9\times 9$ 的盘面上,每个横行、纵列、$3\times 3$ 宫都有完整且不重复的 1 – 9 组合。

现在的问题是,给定一个数独答案,如何用代码验证这个答案的正确性。本文使用 C++ 来实现该目标。

阅读全文 »

在数学中,集合是最基本的概念之一。编程时,我们不可避免地会涉及到集合及其相关操作。在 C++ 中,标准模板库(STL)提供了 std::set/std::unordered_set 两种传统意义上的集合(除此之外,还有 std::multisetstd::unordered_multiset)。其中,std::set(和 std::multiset)定义在头文件 set 当中,从 C++98 起就有支持;而 std::unordered_set(和 std::unordered_multiset)则定义在头文件 unordered_set 当中,从 C++11 开始支持。

此篇我们讨论如何在 C++ 中进行集合的交集和并集操作。

阅读全文 »

这是一篇简短的记录。

某台服务器某账号的 crontab 任务被清空,原因不明。同时,该服务器上的 crontab 任务备份未开启。故思考如何恢复 crontab 任务。

经查,CentOS 系统的 crontab 任务的日志,打印在 /var/log/cron 之中。考虑过滤日志:

1
cat /var/log/cron* | grep CMD | awk -F'CMD' '{print $2}' | awk -F'[(|)]' '{print $2}' | sort -u

由此得到系统记录过的 crontab 执行命令,过滤其他账号的命令后即可追回目标账号的 crontab 任务。

此外,考虑备份 crontab;脚本如下:

backup_crontab.sh
1
2
3
4
5
6
7
8
9
#!/usr/bin/env bash

BACKUP_DIRECTORY="${HOME}/crontab_backup"

if [ ! -e "${BACKUP_DIRECTORY}" ]; then
mkdir -p ${BACKUP_DIRECTORY}
fi

crontab -l > ${BACKUP_DIRECTORY}/$(date '+%Y%m%d').txt

本文以 C++ 为示例语言,但实际其中思想适用范围远大于 C++ 这一编程语言的范畴。

我们知道,C++ 标准模板类库提供了一系列的容器。诸如 std::vector<ElementType> 的容器需要在声明时指定容器中所储存的元素的类型。例如,我们可以使用 std::vector<int> 声明一个包含整型数字的变长数组;而 std::vector<std::string> 则可以用来声明一个包含 std::string 的变长数组。

显而易见,由于容器在声明时就已指定了其包含的元素的类型,容器内只能包含相同类型的元素。这与面向对象编程(Object-Oriented Programming, OOP, 使用继承和运行时动态绑定的编程方式)的思想似乎是矛盾的。因为 OOP 使用继承和动态绑定,允许程序员将相关但有不同的类的共性部分抽象成基类而将这些不同的部分分别作为子类独有的成员;若是容器内只能包含相同类型的元素,我们就无法直接在一个容器中包含同一个基类不同派生类的对象了——而在实际应用中,这种场景是存在的。

前作中最后的示例(动物园的例子)中,我们通过保存基类指针(而不是对象本身)部分解决了这个问题。然而,在前例中,我们不可避免地还是需要使用 newdelete 来动态分配内存。此篇我们通过构建「代理类」来避免手工动态分配内存。

阅读全文 »