【问题标题】:How to efficiently extract unique values from array?如何有效地从数组中提取唯一值?
【发布时间】:2012-02-07 13:50:56
【问题描述】:

我想从我的(动态分配的)数组中提取唯一值。我有这样的事情:

    [0]     0   int
    [1]     1   int
    [2]     2   int
    [3]     2   int
    [4]     2   int
    [5]     5   int
    [6]     6   int
    [7]     6   int
    [8]     8   int
    [9]     9   int
    [10]    10  int
    [11]    8   int
    [12]    12  int
    [13]    10  int
    [14]    14  int
    [15]    6   int
    [16]    2   int
    [17]    17  int
    [18]    10  int
    [19]    5   int
    [20]    5   int

我想要一个大小为 12 的数组,其中的每条记录都是另一个数组的唯一值。

我该怎么做?

编辑 我忘了提到我不能使用 STL 容器(比如 std::vectorstd::list

【问题讨论】:

  • 你知道动态分配数组中的最大值和最小值吗?
  • @Jayantha 我可以得到这个值是的。但是为了什么?
  • @Patryk:你能用 STL 算法吗?
  • @Patryk:我猜 Jayantha 的问题是这些值是否是固定的并且 small(根据一些小的定义)......可能的意图是你可以创建一个N bool 的数组(或使用位图),遍历数组 O(N) 标记存在的元素。然后位图将包含原始数组中存在的一组值。

标签: c++ arrays element unique


【解决方案1】:

使用您最喜欢的排序算法(例如std::sort)对数组进行排序后使用std::unique

编辑: 如果没有 STL,最简单的解决方案是在数组中找到最小值和最大值,然后动态分配 bool 的数组。遍历数组,如果看到元素,将对应的bool 元素设置为true。使用唯一元素的总数分配一个新的int 数组,并用bool 数组中的数据填充它。

推荐: 对数组进行排序并删除连续的元素。实现快速排序并不太难,如果您正在处理整数,radix sort 可能会更好。

【讨论】:

    【解决方案2】:

    您可以使用std::set。将所有元素添加到其中,最后只会出现唯一值。

    【讨论】:

      【解决方案3】:

      首先您需要对数组进行排序,然后遍历排序后的数组并检查上一个或下一个条目是否与当前条目相同。如果不是,则该值是唯一的。

      编辑:我可能误解了这个问题...获得所需内容的一种方法是遍历数组。对于每个值,检查该值是否已存在于另一个数组中,如果不存在则将其复制到那里。这可能需要分两步完成,一个是获取唯一条目的number 个(使用与现有大小相同的数组),另一个是获取一个正确大小的数组。

      【讨论】:

        【解决方案4】:
        #include <iostream>
        #include <stdlib.h>
        using namespace std;
        
        int cmpfun(const void * a, const void * b){
          return (*(int*)a - *(int*)b);
        }
        int main(){
          int n,i,j=0;
          cout<<"Enter the number of elements in the array:\n";
          cin>>n;
          int arr[n],arr_new[n];
          for(i=0;i<n;i++)
               cin>>arr[i];
          qsort(arr, n, sizeof(int), cmpfun); /*Sorting the array; if you aren't allowed to use any library sorting method,
                                           then I suggest to implement one sorting function on your own.*/
        
          for(i=0;i<n;i++){
               arr_new[j++]=arr[i];
                // Excluding all duplicates
               while(i<(n-1) && arr[i]==arr[i+1])
                         i++;
          }
          for(i=0;i<j;i++)
          cout<<arr_new[i]<<" ";
        
        return 0;}
        

        主要目的是确保忽略重复项。因此,您应该首先对数组进行排序,然后在 O(n) 时间内遍历数组,忽略所有重复。在遍历数组时,将所有唯一值(您第一次遇到的值)复制到新数组中。

        我发现唯一让您担心的是旧数组中元素的相应顺序不会保留在新数组中。但是,如果您只关心查找唯一值,那么此方法应该可以正常工作。

        【讨论】:

          【解决方案5】:

          您可以使用散列集 (unordered_set) 来存储源数组的每个值。该集合将自动仅存储唯一值。然后,如果你真的需要一个数组而不是一个集合,你可以创建一个大小合适的数组并用集合的元素填充它。

          【讨论】:

            【解决方案6】:

            如果您知道最大值和最小值,您可以创建一个包含所有可能值的新数组,然后循环遍历您的动态数组。对于每个值,将新数组设置为 1,并将其作为值的索引。 举个例子:- 说你有这样的数据1,2,2,4,6

            如果范围是 1 到 7

            第二个数组会是这样的

            1 2 3 4 5 6 7
            1 1 0 1 0 1 0
            

            算法的复杂度为 2n

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-10-02
              • 2018-09-25
              相关资源
              最近更新 更多