DAU 统计

今日头条2017实习生招聘418在线笔试编程
时间限制:C/C++语言 2000MS;其他语言 4000MS
内存限制:C/C++语言 32768KB;其他语言 557056KB
题目描述:
日活跃用户数 (DAU) 是衡量一个产品表现的重要指标。
需要编写程序,根据给定的某一天的 n 条访问记录,对当天的用户总数 m 进行统计。
每个用户可能访问多次。

输入
每一行包含一个 uid,遇到 0 时认为输入结束。
输入共包含 n+1 行,可认为是无序的。
输出
一个数字:去重后 uid 的数量 m。
样例输入
12933
111111
59220
69433
59220
111111
0
样例输出
4
Hint
数据范围
0 < uid < 2^63
对于 30% 的数据,0 < n < 100,000, 0 < m < 100,000
对于 100% 的数据,0 < n < 1,000,000, 0 < m < 800,000

解决方案

1 使用set就可以了。

2 如果数据量大而稠密,而且最大值为2^32次方,则可以使用bitmap算法来做更好,并使用位算法来统计1的个数。

3 使用Hyperloglog算法

好像是一个近似的概率算法

[Damn Cool Algorithms: Cardinality Estimation]

4 还有直接上代码的另一种hash算法

def trailing_zeroes(num):
  """Counts the number of trailing 0 bits in num."""
  if num == 0:
    return 32 # Assumes 32 bit integer inputs!
  p = 0
  while (num 
>
>
 p) 
&
 1 == 0:
    p += 1
  return p

def estimate_cardinality(values, k):
  """Estimates the number of unique elements in the input set values.

  Arguments:
    values: An iterator of hashable elements to estimate the cardinality of.
    k: The number of bits of hash to use as a bucket number; there will be 2**k buckets.
  """
  num_buckets = 2 ** k
  max_zeroes = [0] * num_buckets
  for value in values:
    h = hash(value)
    bucket = h 
&
 (num_buckets - 1) # Mask out the k least significant bits as bucket ID
    bucket_hash = h 
>
>
 k
    max_zeroes[bucket] = max(max_zeroes[bucket], trailing_zeroes(bucket_hash))
  return 2 ** (float(sum(max_zeroes)) / num_buckets) * num_buckets * 0.79402

类似的问题

查找数组中重复的数

从0到n-1的n个数的数组中查找有重复的数:Given an array of n elements which contains elements from 0 to n-1, with any of these numbers appearing any number of times. Find these repeating numbers in O(n) and using only constant memory space.

For example, let n be 7 and array be {1, 2, 3, 1, 3, 6, 6}, the answer should be 1, 3 and 6.

一种解决方法是

traverse the list for i= 0 to n-1 elements
{
  check for sign of A[abs(A[i])] ;
  if positive then
     make it negative by   A[abs(A[i])]=-A[abs(A[i])];
  else  // i.e., A[abs(A[i])] is negative
     this   element (ith element of list) is a repetition
}

但是如果有k>3次以上重复就会输出k-1次相同的数,当然也可以改进好。

[Find duplicates in O(n) time and O(1) extra space | Set 1]

所以lz觉得还不如使用bitmap算法,更省内存,速度也快,重复多少次也可以。具体可参考[BitMap算法]示例。

results matching ""

    No results matching ""