Python程序员面试算法宝典---解题总结: 第三章 二叉树 3.14 如何实现反向DNS查找缓存

# -*- 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()

猜你喜欢

转载自blog.csdn.net/qingyuanluofeng/article/details/92072107