ARTS - No.4
A
前缀树
刷到一个公共前缀题目,想起来很久以前见过的奇妙数据结构之一——前缀树。
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串
""。示例 1:
输入: ["flower","flow","flight"] 输出: "fl"示例 2:
输入: ["dog","racecar","car"] 输出: "" 解释: 输入不存在公共前缀。说明:
所有输入只包含小写字母
a-z。
题目并不复杂,把每个字符串,依次拿出一个一个字符去对比也可以解决问题。当然,用前缀树也是一种解决办法,我看到的奇妙的地方是用 Python 语言的 defaultdict 结构递归构造前缀树。代码如下:
# 代码参考 python3创建一个trie的两种方法
# https://blog.csdn.net/qq_38619744/article/details/80457573?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
# 已经搞不清楚哪里是原创了……
from collections import defaultdict
from functools import reduce
TrieNode = lambda: defaultdict(TrieNode)
class Trie:
def __init__(self):
self.trie = TrieNode()
def insert(self, word):
reduce(dict.__getitem__, word, self.trie)['end'] = True
def search(self, word):
return reduce(lambda d,k: d[k] if k in d else TrieNode(), word, self.trie).get('end', False)
def startsWith(self, word):
return bool(reduce(lambda d,k: d[k] if k in d else TrieNode(), word, self.trie).keys())
奇妙的就是TrieNode = lambda: defaultdict(TrieNode)和reduce(dict.__getitem__, word, self.trie)['end'] = True这两句,非常简洁。
用print(type(TrieNode))打印TrieNode类型,结果是<class 'function'>,所以self.trie是一个TrieNode({str: TrieNode(...)})这样的递归字典,结构很神奇。
(神奇就神奇吧,分享下这个结构就行了,前面放一道题目是干啥的呢?当然是占篇幅了,哈哈哈哈哈……)
R
故事要从 C语言的整型溢出问题 说起,然后就看到参考链接 INT32-C. Ensure that operations on signed integers do not result in overflow 这里,感觉写得挺好,所以顺手翻译了一下。
翻译的文档放在 GitHub 上面: SEI-CERT-C-Coding-Standard / INT32-C. Ensure that operations on signed integers do not result in overflow (不过我水平有限,有些地方不太明白,翻译不出来)
T
之前看 C 语言的可变参数,在vadefs.h头文件里有一个 INTSIZEOF 宏,获取类型占用的空间长度,最小占用长度为int的整数倍:
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
比如在 32 位机器上,int类型的长度是 4 字节,char是 1 字节,那么_INTSIZEOF(char)就是 4 。这个宏用来干什么呢?当然是字节对齐啦。
还是以 32 位机器为例,不管变量长度是多少,指针变量长度一定是 4 字节,所以寻址任何一个变量,都需要向 4 字节的整数倍对齐。这就对应到可变参数上了,printf函数就是这么找到参数里的各种奇奇怪怪的变量的。
S
取法其上,得乎其中;取法其中,得乎其下;取法其下,法不得也。

浙公网安备 33010602011771号