寻找n个阵列中的独特元素

时间:2013-11-02 02:09:07

标签: c++ arrays algorithm unique

我正在尝试编写一个算法,该算法采用可变数量的通用数组,存储在d_arrays中,并收集它们中的所有唯一元素(仅出现一次的元素)并将它们存储在数组中,叫d_results。例如,数组:

int intA[] = { 12, 54, 42 };
int intB[] = { 54, 3, 42, 7 };
int intC[] = { 3, 42, 54, 57, 3 };

会生成包含内容d_results的数组{ 12, 7, 57 }

这是我目前的流程算法:

template <class T>
inline
void UniqueTableau<T>::run() {
    T* uniqueElements = d_arrays[0];
    int count = 0;
    for (int i = 1; i < d_currentNumberOfArrays; ++i) {
        if (count == 0) {
            uniqueElements = getUnique(uniqueElements, d_arrays[i], d_sizes[i - 1], d_sizes[i]);
            ++count;
        }
        else {
            uniqueElements = getUnique(uniqueElements, d_arrays[i], d_numberOfElementsInResult, d_sizes[i]);
        }
    }
    d_results = uniqueElements;
}

template <class T>
inline
T* UniqueTableau<T>::getUnique(T* first, T* second, int sizeOfFirst, int sizeOfSecond) {
    int i = 0;
    int j = 0;
    int k = 0;
    T* uniqueElements = new T[sizeOfFirst + sizeOfSecond];
    while (i < sizeOfFirst) {    // checks the first against the second
        while ((first[i] != second[j]) && (j < sizeOfSecond)) {
            ++j;
        }
        if (j == sizeOfSecond) {
            uniqueElements[k] = first[i];
            ++i;
            ++k;
            j = 0;
        } else {
            ++i;
            j = 0;
        }
    }
    i = 0;
    j = 0;
    while (i < sizeOfSecond) {    // checks the second against the first
        while ((second[i] != first[j]) && (j < sizeOfFirst)) {
            ++j;
        }
        if (j == sizeOfFirst) {
            uniqueElements[k] = second[i];
            ++i;
            ++k;
            j = 0;
        } else {
            ++i;
            j = 0;
        }
    }

    T* a = new T[k];    // properly sized result array
    for (int x = 0; x < k; ++x) {
        a[x] = uniqueElements[x];
    }

    d_numberOfElementsInResult = k;
    return a;
}

请注意,d_sizes是一个数组,其中包含d_arrays中每个数组的大小,而d_numberOfElementsInResultd_results中元素的数量。

现在,这个数组正在做的是一次比较两个,获取这两个元素之间的唯一元素,并将这些元素与下一个数组进行比较,依此类推。问题是,当我这样做时,有时会有一些元素,例如,第三个数组和前两个元素的唯一元素之间是唯一的,但在第三个和第一个元素之间不是唯一的。这是令人困惑的措辞,所以这是一个使用上面的数组的可视化示例:

首先,算法找到第一个和第二个数组的唯一元素。

{ 12, 3, 7 }

现在,它会针对第三个数组进行检查,在这些数组之间产生唯一的元素。

{ 12, 7, 42, 54, 57 }

右?错误。这里的问题是,由于4254没有出现在唯一数组中,它们最终会出现在最终产品中,即使它们对所有三个数组都是通用的。

有人能想到这个解决方案吗?对此算法的更改是首选,但如果不可能,那么解决此问题的另一种方法是什么?

3 个答案:

答案 0 :(得分:2)

编辑:正如所指出的那样,算法是O(nlogn)时间和O(n)空间复杂度。

遍历所有数组中的每个元素,并形成每个遍历项目计数的映射。

创建地图后,只需遍历它并形成计数为1的那些元素的数组。

答案 1 :(得分:0)

记忆是问题,虽然我会以不同的方式做到这一点(由于缺乏经验?) - 实际上我正在考虑刚刚发布的答案!

无论如何,不​​要扔掉你的副本并将它们保存在辅助数组中。获取此数组并将其附加到每个新数组两次,这将使您的算法几乎没有变化。只有更改才会创建重复项并每次查看更大的列表。虽然这增加了时间和记忆。如果这是一个问题,那么请使用第一个发布的答案!

答案 2 :(得分:0)

解决方案1:

  1. 只需将所有数组的所有元素都放入一个。
  2. 对数组进行排序
  3. 删除重复。
  4. 解决方案2:

    1. 创建一个map,其中key是元素,值是boolean
    2. 只是遍历个别数组。如果元素不在地图中,则将key作为元素,将值设置为true。但是,如果元素已经存在,则将值设为false。
    3. 现在只需打印地图中的元素,该元素的值为true,即只发生一次。
    4. 为什么我将值设置为布尔值而不是整数:

      我们知道如果地图中存在key形式的元素,则表明元素存在于数组中。因此,如果我们下次再次发现错误,如果我们再次找到该元素则显示重复。希望你明白。