【问题标题】:How to count unique items in a list?如何计算列表中的唯一项目?
【发布时间】:2011-03-14 14:15:54
【问题描述】:

有人会如何继续计算列表中唯一项目的数量?

例如说我有 {1, 3, 3, 4, 1, 3} 并且我想得到代表列表中唯一项目数的数字 3(即 |A|=3 if A={ 1、3、4})。有人会为此使用什么算法?

我尝试了双循环:

for firstItem to lastItem
  currentItem=a
  for currentItem to lastItem
    currentItem=b
    if a==b then numberOfDublicates++
uniqueItems=numberOfItems-numberOfDublicates

这不起作用,因为它计算的重复次数比实际需要的次数多。以开头的示例为例:

  1. 对于第一个循环,它将计算列表中第 1 位的 +1 个重复项。
  2. 对于第二个循环,它将计算列表中第 3 位的 +2 个重复项。
  3. 对于第三个循环,它会再次计算数字 3 的 +1 重复项(多算最后一个 '3')和 这就是问题所在。

你知道如何解决这个问题吗?

【问题讨论】:

    标签: algorithm list count unique items


    【解决方案1】:

    将项目添加到 HashSet,然后在完成后检查 HashSet 的大小。
    假设你有一个很好的哈希函数,这是O(n)。

    【讨论】:

    • 这不适用于纯 C,对吧?因为我能想到的唯一方法是检查一个哈希是否已经存在于一个数组中并给出第二个循环。这提供了超过 O(n) 的时间。
    • @Pithikos:错误;您可以将哈希直接转换为数组索引。阅读哈希表; en.wikipedia.org/wiki/Hash_table
    • 任何算法或技术都可以用任何(体面的)图灵完备语言实现,尽管可能需要更多的努力。 任何事情都可以用纯C语言完成。
    • @SLaks:平均为 O(n)(因为您使用的是哈希表)。
    • @unforgiven:什么意思?
    【解决方案2】:

    您可以检查号码后面是否有任何重复。如果不增加 uniqueCount:

    uniqueCount = 0;
    for (i=0;i<size;i++) {
      bool isUnique = true;
      for (j=i+1;j<size;j++)
         if (arr[i] == arr[j] {
           isUnique = false;
           break;
         }
      }
      if(isUnique) {
        uniqueCount ++;
      }
    }
    

    上述方法是时间上的O(N^2),空间上的O(1)。

    另一种方法是对输入数组进行排序,这会将重复的元素彼此相邻,然后查找相邻的数组元素。这种方法在时间上是O(NlgN),在空间上是O(1)。

    如果允许您使用额外的空间,您可以通过使用哈希在O(N) 时间和O(N) 空间中完成此操作。哈希的键是数组元素,值是它们的频率。

    在散列结束时,您只能获得值为1 的那些散列键的计数。

    【讨论】:

      【解决方案3】:

      使用像mergesort或heapsort这样的排序算法对它进行排序(最坏情况都是O(n log n))并循环排序列表:

      sorted_list = sort(list)
      unique_count = 0
      last = sorted_list[0]
      
      for item in sorted_list[1:]:
        if not item == last:
          unique_count += 1
        last = item
      

      【讨论】:

      • 你可以比O(n logn)做得更好。
      【解决方案4】:
      list.sort();
      for (i = 0; i < list.size() - 1; i++)
        if (list.get(i)==list.get(i+1)
          duplicates++;
      

      【讨论】:

        【解决方案5】:

        保留字典并在循环中添加计数

        这就是它在 c# 中的样子

        int[] items = {1, 3, 3, 4, 1, 3};
        Dictionary<int,int> dic = new Dictionary<int,int>();
        foreach(int item in items)
           dic[item]++
        

        C# 中当然有 LINQ 方式,但据我所知,问题很笼统;)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-02-13
          • 2012-08-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多