# -*- coding: utf-8 -*-
'''
Python程序员面试算法宝典---解题总结: 第三章 二叉树 3.14 如何实现反向DNS查找缓存
题目:
反向DNS查找指的是使用Internet IP地址查找域名。例如,如果你在浏览器中输入
74.125.200.106,它会自动重定向到google.com。
如何实现反向DNS查找缓存。
分析:
最简单的方法就是用一个字典,建立
<ip, 域名>的字典。
因为考虑的是缓存,所以设置有效时间。
如果缓存超过有效时间,则执行一次ip地址到域名的解析,然后再次存入到其中。
所以,建立的<ip, [域名,过期时间]>这种映射。
关键:
1 书上解法
采用Trie树,就是前缀树。
在Trie树种存储IP地址,最后一个节点存储对应的域名。
2 Trie树的实现过程。
构造Trie树过程:
74.125.200.106
对每个字符构建一个节点,到最后一个字符对应的节点创建完成后,将该节点下面创建一个节点存储域名。
本质是一个多叉树。
每个节点都有一个 child数组,长度为11(0到9和一个. 共有11个字符)。
这里实际就是一个多叉树的建立
3 ord(c)
表示获取字符c对应的ascii码
4 我之所以没有想到
是因为忘记trie树在搜索和字符串查找方面的应用了。
ttie的时间复杂度应该就是待查找的字符串的长度。
trie树本身实质上是一个多叉树。
参考:
Python程序员面试算法宝典
'''
NUM_SET = set([str(i) for i in range(10)])
NUM_LIST = set(list(range(11)))
class TrieNode(object):
def __init__(self, char=None):
self.count = 11
self.childs = [None for i in range(self.count)]
self.isLeaf = False
self.char = char
self.leaf = None
def getIndex(self, char):
result = None
if '.' == char:
return 10
elif char in NUM_SET:
result = ord(char) - ord('0')
return result
else:
return result
def getChar(self, index):
if index not in NUM_LIST:
return
if index == 10:
return '.'
else:
return str(index)
class DNSTrieTree(object):
def __init__(self):
self.root = TrieNode()
def insert(self, ip, url):
if not ip:
return
node = self.root
for char in ip:
index = node.getIndex(char)
child = node.childs[index]
if child is None:
child = TrieNode(char)
node.childs[index] = child
node = child
node.isLeaf = True
node.leaf = url
def search(self, ip):
node = self.root
for char in ip:
index = node.getIndex(char)
child = node.childs[index]
if child is None:
node = child
break
node = child
if node and node.isLeaf:
return node.leaf
return None
def process():
tree = DNSTrieTree()
tree.insert('1.2.3.4', 'baidu.com')
result = tree.search('1.2.3.4')
print result
tree.insert('2.2.3.4', 'sina.com')
result = tree.search('2.2.3.4')
print result
tree.insert('1.2.3.4', 'baidu.com')
result = tree.search('1.2.3.4')
print result
if __name__ == "__main__":
process()