1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
| ''' 电话聊天狂人 n 13151548956 18514547845 18615611548 13774574851 13151548956 16854975848 13151548956 13774574851
统计哪一个号码的接电话和打电话的总次数是最多的?
解法1: 排序 1、读入号码,每个号码是11长度的字符串。 2、排序。 3、扫描有序数组,累计同号码出现的次数,并更新最大次数。 优点; 这种思路非常简单,适合在考试的时候解题用,但是在工程问题时不适用, 缺点: 不方便拓展。无法解决"动态插入"的问题。 比如新加入n个数据,每加入一个数据,就问一个 "聊天狂人", 每次都排序就要NlogN,大约就是N^2logN 。
解法2: 直接映射(桶排序) 1、创建全单元数的整数数组,保证每个号码对应唯一的单元下标,数组初始化为0。 2、对读入的每一个点好号码,找到对应单元,数值累计1次。 3、顺序扫描数组,找出累计次数最多的单元。 优点: 编程简单快捷额,主要是思路简单。 缺点: 下标是 11 位长的电话号码,一般用的整数是10位的, 就算用了longlong的整数,11位的数字(第一个位置总是1),一个数字2byte,也有2*10^10个byte。 占内存空间太大, 一行两个号码 ,需要 (2*10^10)*2 bytes = 37 G。 假如问题中 n 是 10^5 ,最多也就 2*10^5个电话号码, 但 总单元数 是固定的,都是2*10^10个单元, 也就是说不同规模的问题,都需要扫描这样一个巨大数量。 所以这个解法无论是时间复杂度还是空间复杂度,都不行。仅仅只是想的挺美好。
解法3: 带智商的散列 手机号 123 4567 89 10 11 网络识别号 地区编码 用户随机 由于前面的一些位数重复率太高,会导致太多元素被映射到同一个区域, 合理的方法: 把最后5位 ,就是一个地区号加用户随机的号码组成5位,用于散列。 假如有 N 行,最多就有 2N 个电话号码, 取 p 略大于 2N 的质数,构建 p 个空位的数组。 用分离链接法处理冲突。 h(key) 我们直接简单的用除留余数法。 在插入一个新的号码时,要先在 h(key)位置遍历搜索一次链表, 如果已经存在这个号码,就在这个号码的链表结点的计数属性中+1, 如果不存在这个号码,就在链表的头部插入这个包括这个号码的结点。
def main(): 创建散列表 读入号码插入表中 扫描表,找出输出狂人
'''
class HashTable(): class Node(): def __init__(self, data, cum=1, next=None): self.data = data self.cum = cum self.next = next def __init__(self,tablesize): self.TableSize = tablesize self.TheList = [None for _ in range(self.TableSize)] def Hash(self,item): return int(item[-5:])%self.TableSize def Find(self,item): Pos = self.Hash(item) node = self.TheList[Pos] while node != None and node.data != item: node = node.next return node def Insert(self,item): node = self.Node(item) Pos = self.Hash(item) P_node = self.TheList[Pos] if self.TheList[Pos] == None: self.TheList[Pos] = node elif P_node.data == node.data: P_node.cum += 1 else: while P_node.next != None and P_node.next.data != node.data: P_node = P_node.next if P_node.next == None: P_node.next = node elif P_node.next.data == node.data: P_node.next.cum += 1 def Delete(self,item): node = self.Find(item) if node == None: print("要找的内容'%d'不在hash表中。"%item) return Pos = self.Hash(item) P_node = self.TheList[Pos] if P_node == node: self.TheList[Pos] = node.next return while P_node.next != node: P_node = P_node.next P_node.next = node.next
def main(): A = [[10], ['13142514512','12345678987'], ['18443141262','18397431567'], ['18515678345','18397431567'], ['18397431567','18515678345'], ['18515678349','18515678349'], ['18515678349','18515678349'], ['18515678349','18515678349'], ['15233334444','15233334444'], ['15233334444','15233334444'], ['15233334444','15233334444']] N = len(A) A.pop(0) H = CreatTable(N*2) for i in range(N-1): H.Insert(A[i][0]) H.Insert(A[i][1]) ScanAndOutput(H)
def CreatTable(N): def NextPrime(N): Maxtablesize = 1000000 p_fun = lambda N: N + 2 if N % 2 else N + 1 p = p_fun(N) while p <= Maxtablesize: for i in range(int(p ** (1 / 2)), 2, -1): if p % i == 0: break if i == 3: break else: p += 2 return p nextprime = NextPrime(N) h = HashTable(nextprime) return h
def ScanAndOutput(H): the_most = 0 statistics = [] for node_point in H.TheList: while node_point != None: statistics.append(node_point) node_point = node_point.next def Insert_Sort(A): for p in range(1, len(A)): temp_cum = A[p].cum temp_node = A[p] preIndex = p - 1 current = p while A[preIndex].cum > temp_cum and preIndex >= 0: A[current] = A[preIndex] current = preIndex preIndex = current - 1 A[current] = temp_node Insert_Sort(statistics) result_list = [] print('电话狂人是:%s' % statistics[-1].data) for i in range(len(statistics)-1,-1,-1): result_sort = statistics[i].data,statistics[i].cum result_list.append(result_sort) if statistics[i].cum == statistics[-1].cum: print('电话狂人并列第一的是:%s'%statistics[i].data) print('电话狂人从大到小依次是:',result_list)
if __name__ == '__main__': main()
|