WordPress 的 Github Fetcher 插件

关于最新的介绍和使用安装方式, 建议参考 Github 的 ReadMe.md. 好长时间没有写博客, 主要的原因是比较忙. 这段时间要搞定工作上的事情, 还要处理房屋的装修, 顺便还要准备结婚的事情, 有点焦头烂额. 所以, 也是上班的时候, 抽了一个小时搞定了这个插件. 我个人写博客的习惯是, 本地上写好了博客, 然后提交到自己的 git 库里面, 然后 push 到 github 上. 之前在用 emlog 的时候, 也是自己写了一个同步的插件来帮助同步, 加上 github 的 markdown 渲染效果确实可以, 同时还可以用他们的图片作为 CDN 的加速. 具体细节也不多说, 然后就是具体的使用方法. 如何安装 直接到 github 的 release 页面, 下载 zip 包, 然后通过上传文件的安装方式安装该插件就可以了. TODO: 将插件上传到官方的插件中心 如何使用 通常, 当安装插件之后, 你会看到在编辑器的右侧看到一个对话框, 输入你的 github 博客文章地址, 对于我来说, 通常而言就是 https://github.com/xxx/xx.md, 然后按 Sync 按钮, 之后就可以看到同步好的博客出现在编辑器里了. 目前, 这个插件只支持老版本的编辑器, 对于最新的编辑器 – Gutenberg 并不支持. (说句实话, 新版本的编辑器太难用…) 最后, 如果觉得有用, 有新的需求, 欢迎在 github 上提交 issue. 如果担心是否能同步图片和代码, 可以参考如下的测试部分: using namespace std; class Solution { public: void dfs(vector<vector<int>> &grid, set<pair<int, int>> &points, int idx, int idy) { if (0 <= idx && idx < (int)grid.size() && 0 <= idy && idy < (int)grid[0].size()) { if (points.find(pair<int, int>(idx, idy)) != points.end() || grid[idx][idy] == 0) { return; } points.insert(pair<int, int>(idx, idy)); dfs(grid, points, idx – 1, idy); dfs(grid, points, idx, idy – 1); dfs(grid, points, idx + 1, idy); dfs(grid, points, idx, idy + 1); } } int largestIsland(vector<vector<int>> &grid) { set<pair<int, int>> points; vector<vector<pair<int, int>>> groups( grid.size(), vector<pair<int, int>>(grid[0].size(), pair<int, int>(0, 0))); int maxSize = 0; int groupIdx = 1; vector<pair<int, int>> zeros; for (int i = 0; i < (int)grid.size(); i++) { for (int j = 0;…

Firefox 完全暗黑主题

我是实在想不到什么比较好的名称了… 所以才写了这么个标题. 事情的起因是这样的, 因为最新的 MacOS 已经有了暗黑主题, 所以作为最顺手的浏览器 – Firefox 也遇到了一个新的问题, 就是能否以最完美的姿态迎接这个新的主题. 我们可以先看看正常情况下的火狐浏览器的表现, 即官方的 dark 主题: 可以看到,右键菜单和下来书签都是白色的, 很扎眼. 所以尝试修改了火狐的主题, 新版的效果如下: 从我的个人审美看, 更加喜欢改好的这个主题. 具体的代码在这 具体的安装方法就是找到火狐的 Profile 文件夹, 然后将代码 git clone 到 chrome 文件夹下. 具体的位置可以看我之前的文章 这边推荐下 Fira Code 这个字体, 一开始因为他的 programming ligatures 不太习惯, 但是习惯之后, 确实发现代码的可读性变得很高. 虽然对于一般的新手玩家, 都会推荐 Chrome 作为主要浏览器, 不过如果喜欢折腾, Firefox 显然有着更加充分的自由度. 作为一个从 Firefox 3 开始使用的用户, 真的不忍心看到它被埋没啊.

01 背包的二进制优化

也是在刷题的时候发现的,比如 hiho week 195。一眼看过去就是一个 0-1 背包问题,然后直接 DP 上了,当时觉得应该问题不大,结果最后只有 50%,一看数据,100% 的数据为 1E5 量,简单的 DP 的话复杂度为 O(MN),这样复杂度估计是 1E10,这样肯定会 TLE。 然后一看,他的单个商品的全权值很低,都在 [1, 10] 之间,这样的话,最多有 100 种组合,所以极端情况下,每个商品都会有 1000 个同类。这样就有了二进制优化的余地。简单的说就是,将多个重复的商品进行优化。比如 p(w, v) 的商品有 10 个,那么,我们可以将其简化为,一个 p(1w, 1v),一个 p(2w, 2v),一个 p(4w, 4v),最后剩下一个 p(3w, 3v)。 这样的话,就将数据量从 10 简化到了 4。于是乎,就可以将数据量减少一个数量级。所以,最后这题的代码: using namespace std; typedef pair<uint64_t, uint64_t> pii; typedef pair<pii, uint64_t> ppiii; typedef pair<pii, pii> ppiipii; int main() { ios::sync_with_stdio(false); uint64_t n, m; cin >> n >> m; map<pii, uint64_t> _ticks; for (uint64_t i = 0; i < n; i++) { uint64_t w, p; cin >> w >> p; _ticks[pii(w, p)]++; } vector<pii> ticks; for (auto tick : _ticks) { uint64_t idx = 0; uint64_t remain = tick.second; while (remain > 0) { uint64_t cur = pow(2, idx); idx++; if (remain >= cur) { ticks.push_back(pii(cur * tick.first.first, cur * tick.first.second)); } else { ticks.push_back( pii(remain * tick.first.first, remain * tick.first.second)); cur = remain; } remain = remain – cur; } } vector<vector<uint64_t>> DP(2, vector<uint64_t>(m + 1, 0)); for (uint64_t i = ticks[0].first; i <= m; i++) { DP[0][i] = ticks[0].second; } for (uint64_t i = 1; i < (uint64_t)ticks.size(); i++) { uint64_t cur = i % 2; uint64_t pre = (i – 1) % 2; for (uint64_t j =…

二分查找和 Lucas 定理

因为这段时间都在打比赛中度过,有几个小的收获点这边可以留个纪念。 1. 二分查找的几个用法。 一般而言,二分查找都是用在不同数字的数量集中。这样的好处是如何快速的定位。但是,如果是排序的包含相同数字的数组,要求获得某一个数出现的次数时,就得用另一种二分查找的变种了。 假设是 [1, 1, 2, 3, 3] 这样的一个数组,要求获得 1 和 3 的个数时。普通的二分查找只能定位到其中的一个位置。之前我的做法是,向前向后搜索。但是,在极端情况下,比如一整个数组都是 1,此时,算法的复杂度退化为 O(N),然后就 TLE 了。 所以这边也正好是看到【剑指 offer 】里面有这么一题,就写一下。 int getFirstIdx(vector<int> &nums, int target) { if (nums.size() == 0) { return -1; } int left = 0, right = nums.size() – 1; do { int mid = left + (right – left) / 2; if (mid == target) { if (mid == 0 || (mid > 0 && nums[mid – 1] != target)) { return mid; } else { left = mid – 1; } } else if (mid > target) { right = mid – 1; } else { left = mid + 1; } } while (left <= right); return -1; } int getLastIdx(vector<int> &nums, int target) { if (nums.size() == 0) { return -1; } int left = 0, right = nums.size() – 1; do { int mid = left + (right – left) / 2; if (mid == target) { if (mid == (int)nums.size() – 1 || (mid < (int)nums.size() – 1 && nums[mid + 1] != target)) { return mid; } else { right = mid + 1; } } else if (mid > target) { right = mid – 1; }…

MJsonViewer v2.0 插件发布

可能是第一个支持嵌套 json 解析的火狐 json 插件。正如,之前写的那样,因为持续开发,主要是因为喜欢火狐,而且确实有新的需求进来了。 距离上一次的插件发布已经过去了两个多月了,其实总的使用下来还是比较舒服的。不过,有几个小的缺点也还是要说一下。如果一个 json 中的 k-v 的 v 包含了一个嵌套的 json,一般的 json 解释器都是将其作为 string 来解析。 这就带来了一个问题。在软件开发中,我们经常会在 json 中嵌套 json,从而导致在浏览器中的浏览体验极差。加上最近的四个需求: MikeCoder/MJsonViewer [Feature request] Detect if a string value contains JSON and provide an option to format it enhancement MikeCoder/MJsonViewer [Feature request] Option to hide items and bytes counters enhancement MikeCoder/MJsonViewer [Feature request] Alternative Content-Types are not supported (e.g. application/hal+json) enhancement MikeCoder/MJsonViewer [Feature request] Folding for very long strings 我就决定先写一个验证测试版本出来,不过之后的主要任务就是在不破坏原有 json 结构的情况下更好的实现内部 json 的解析。 这个也算是,在总用户到达 2.5k 之后,的一个小的升级吧。 下载地址:https://addons.mozilla.org/en-US/firefox/addon/mjsonviewer/ 代码地址:https://github.com/MikeCoder/MJsonViewer Done.

JSON 解析器

这篇博客主要是最近开始玩 C,所以准备找个东西练手,突然发现,顺手写个 JSON 解析器吧。于是就开始了。 相对于其他比较成熟的上层语言。C 主要的问题就是没有基础的数据结构,而且相对于弱类型语言而言,C 的类型在解析的时候有个类型转换的坑。但是相对于其他的强类型语言而言,C 又有一个好处,那就是没有一个 void* 解决不了的问题,如果有,那就用两个。 不过相对于工作时的清闲,现在上课的时候确实没有什么时间进行额外的代码编写。所以断断续续写了一周多。 主要的使用方法就是: struct value *val = parse_new(); char *json1 = “{\”fff\”:[2,4,5,6]}”; parse(val, json1); map_display(*(struct map*)val->value); struct value key; key.type = STRING; key.value = (void*)”fff”; list_display(*(struct list*)(map_find(*(struct map*)val->value, key)->value)); 首先初始化一个 val 对象作为头,然后直接调用 parse 函数。这样就可以把数据解析完成了。 其实还是挺简单的。主要的目的也只是检查自己对 C 语言的熟悉程度。目前也只是个简单的版本。之后会慢慢的进行优化。比如目前就不支持 null, 非十进制数字解析等等。 说道 JSON 的解析,其实 JSON 本身的格式非常的简单。按照 官网的说法,状态转换也无外乎以下几种: 相对于细节上,整体看下来的话其实更简单:{ “key”: value } 和 [ value ],而 value 有可能是 list,和 map 两种数据结构。 而判断就是第一个字符是否是 ‘[‘ 或者 ‘{‘。然后就是一个递归向下的解析。 所以总体而言还是简单的。不过写下来的第一个感觉还是觉得 makefile 很棒,通过不同的规则,可以实现粒度为文件的编译控制。不过因为失误(Java 的 import 习惯),导致了一个环形依赖的错误。 不足: 比如,在 list.c 和 map.c 中有 list_display 和 map_display 两个函数,但是,我会在 value.c 中的 value_display 中进行调用。因为需要根据 value->type 的不同,使用不同的 display 方式,所以需要在 value.h 中 include “list.h” 和 “map.h”,但是在这两个文件中,我也需要 include “value.h” 这就带来了环形依赖。解决的办法就是额外增加一个 utils.h 的模块,主要作用就是根据 value->type 的不同来采取不同的展示方法。 同时,前一篇的 C OOP 编程也提到了另一个解决方案,就是通过函数指针来做。这个会在之后完成。 TODO:(闲的时候再做) 支持 JSON 所有的特性,比如各种数字 尽量使用流的方式进行读取,而非现在的先读入再解析 优化基础数据结构,同时优化解析后的读取方式 JSON 吐槽的地方 因为历史原因,JSON 是基于 JavaScript 发展起来的,所以也带上了明显的 JavaScript 标签。有一个非常严重的错误就是,在 json 中,并没有对 number 这个作出明确定义。比如,在 C 中,int 对应的 32 位整形变量。但是 JSON 不管啊,不管多长多大的数字,通通都是 int,甚至远远超出 long long 的范围都不管。 所以,会有这么个现象,在联通 APP 上充值写上 9*10^100 时,使用微信付款,最后微信只需要付款 INT_MAX 即宣告交易成功。(支付宝就么有这个 bug)。如果使用 XML 就有机会减少此类事情的发生。而且在网络上传输的数据,我还是觉得 String 比 number 类型好。 如果说要我选一个通用性更高的协议或者说更完备的序列化手段,messagepack 明显更好。

VIM 浏览器预览插件

插件的地址:GITHUB. 写这个插件的原因很简单。因为之前一直再写一个页面,因为在主力的编辑器是 VIM,所以就顺手用了。但是遇到一个很尴尬的地方,就是在想观看编写的效果的时候,常常会需要使用 Finder,然后进入当前的工作目录,然后双击 html 文件。 非常痛苦。于是去查了下 vim 有没有这么一个插件,可以方便的进行浏览器预览的。 当然也是查到了相关的方式,比如这篇博客: ” 在浏览器预览 for win32 function! ViewInBrowser(name) let file = expand(“%:p”) exec “:update ” . file let l:browsers = { \”cr”:”D:/WebDevelopment/Browser/Chrome/Chrome.exe”, \”ff”:”D:/WebDevelopment/Browser/Firefox/Firefox.exe”, \”op”:”D:/WebDevelopment/Browser/Opera/opera.exe”, \”ie”:”C:/progra~1/intern~1/iexplore.exe”, \”ie6″:”D:/WebDevelopment/Browser/IETester/IETester.exe -ie6″, \”ie7″:”D:/WebDevelopment/Browser/IETester/IETester.exe -ie7″, \”ie8″:”D:/WebDevelopment/Browser/IETester/IETester.exe -ie8″, \”ie9″:”D:/WebDevelopment/Browser/IETester/IETester.exe -ie9″, \”iea”:”D:/WebDevelopment/Browser/IETester/IETester.exe -all” \} let htdocs=’E:\\apmxe\\htdocs\\’ let strpos = stridx(file, substitute(htdocs, ‘\\\\’, ‘\’, “g”)) if strpos == -1 exec “:silent !start “. l:browsers[a:name] .” file://” . file else let file=substitute(file, htdocs, “http://127.0.0.1:8090/”, “g”) let file=substitute(file, ‘\\’, ‘/’, “g”) exec “:silent !start “. l:browsers[a:name] file endif endfunction nmap <f4>cr :call ViewInBrowser(“cr”)<cr> nmap <f4>ff :call ViewInBrowser(“ff”)<cr> nmap <f4>op :call ViewInBrowser(“op”)<cr> nmap <f4>ie :call ViewInBrowser(“ie”)<cr> nmap <f4>ie6 :call ViewInBrowser(“ie6″)<cr> 通过这样的一种方式,进行预览,这显然就能看到局限的部分,就是所有的配置项都需要手动进行修改。非常的麻烦。 而且,通常情况下,我们常常使用的是 Linux 还有 MacOS,不同平台下的配置,也是不同的。于是这个思路进行编写插件,无疑会附带各种平台的依赖。 还好,VIM 支持 python 进行插件开发,而且对于不同平台的配置,他已经做的相当的完善,所以说,如果有这个前人做好的轮子,何苦在自己手工进行环境的配置? 不顾局限也是挺大的,需要 vim 支持 python,不过这一点,基本上大部分的 vim 都已经继承了吧。 插件的地址:GITHUB. 相对来说,依托于 Python,整个代码相当的简短。唯一需要配置的部分,就是列举出,使用改插件的文件后缀名。 let g:open_in_browser_allowed_file_types = { \”html”: 1, \”htm”: 1, \”xml”: 1, \} 这么弄好之后,可以避免在错误的文件类型中,浏览器无法打开的尴尬场面。 最后,磨刀不误砍柴工,vim 最大的好处就是可以在极大提高编写效率的同时,还添加了强大的自定义方式吧。 当然,ATOM 和 Sublime 也相当棒,不过,作为一个常年终端党,能和终端完美结合的也只有 vim 和 emacs 吧。在这一点上,除了会使用 ide 进行 debug,vim 还真的是,完美的编辑器。 又给水了一篇。

VIM Quickrun 插件

这同样是一个重复造轮子的项目,主要的原因就是受大家喜欢的 https://github.com/thinca/vim-quickrun 并不能很好的满足我的需求。 他的运行方式是新开一个 buffer 然后将运行的结果放在 buffer 里面。这样有一个问题就是交互不是很方便。同时,我对这个插件的需求主要还是在写 ACM 的代码时,可以快速的运行。同时在写单脚本语言时,可以方便的配置。 所以,基于以上的几个原因,我自己便开始写了这么一个小插件。 原理其实很简单,就是对你当前的文件名进行一个匹配。比如 “main.cpp”,我会发现这个文件的后缀名是 “cpp”,于是,就会自动查找到配置文件中的 “cpp” 选项。 let g:quickrun_known_file_types = { \”cpp”: [“!g++ %”, “./a.out”], \”c”: [“!gcc %”, “./a.out”], \”php”: [“!php %”], \”vim”: [“source %”], \”py”: [“!python %”], \} 对于插件的默认配置而言就会执行: !g++ currentFile && ./a.out 命令,也就是编译加执行。而且是通过 VIM 的命令行执行的,这样的一个好处就是可以方便的进行用户的交互。上手的难度较小。 其他也不是多说什么,具体的安装和配置文档在: https://github.com/MikeCoder/quickrun.vim 欢迎试用。

Hexo Gandalfr 主题发布

主题地址: hexo-theme-gandalfr 在线预览: Example 起因:因为之前考虑到英文博客的主题问题,之前一直用 even 主题,但是始终觉得不是特别中意。于是找到了 apollo。 发现这是我比较喜欢的类型。简单,足够简单。但是有两点不足: 文章没有 Tag 提示。 文章中的代码段没有高亮。 在较大屏幕上显示的时候,有点小。(主要内容 600px 是有点小了) 所以这边也就是修改了下,并且打包上传。因为原作者已经停止继续开发了。 安装 # cd to your hexo dir npm install npm install –save hexo-renderer-jade hexo-generator-feed hexo-generator-sitemap hexo-browsersync hexo-generator-archive hexo-tag-cloud git clone https://github.com/MikeCoder/hexo-theme-gandalfr.git themes/gandalfr cd themes/gandalfr cp _config.yml.example _config.yml # modify the config file by yourself 配置 theme: gandalfr # Dependent on the hexo-generator-archive plugin archive_generator: per_page: 0 yearly: false monthly: false daily: false 注意需要在 hexo 的根目录里加上 hexo-tag-cloud 的依赖,不然,标签云不显示。即 package.json 文件。 具体的 hexo-tag-cloud 的安装文档可以阅读这: hexo-tag-cloud. 效果展示 首页效果: 文章详情页: 归档页: 其实也是水一篇。。。