Arrays 查找2个排序数组的并集(具有重复项)

Arrays 查找2个排序数组的并集(具有重复项),arrays,algorithm,Arrays,Algorithm,我试图找到2个排序数组的并集(带有重复数组),但我觉得我没有找到最优雅的代码(顺便说一句,我觉得我可以减少一些代码行)。假设我有两个向量a={1,3,3,4,4,5,7}和b={1,3,3,5,5,6,8,9},我想把它们的并集存储在一个称为并集向量的向量中(即1,3,4,5,6,7,8,9) 这是我的密码: #include <iostream> #include <vector> using namespace std; // Prints the contents

我试图找到2个排序数组的并集(带有重复数组),但我觉得我没有找到最优雅的代码(顺便说一句,我觉得我可以减少一些代码行)。假设我有两个向量a={1,3,3,4,4,5,7}和b={1,3,3,5,5,6,8,9},我想把它们的并集存储在一个称为并集向量的向量中(即1,3,4,5,6,7,8,9)

这是我的密码:

#include <iostream>
#include <vector>
using namespace std;

// Prints the contents of a vector
void printVector(vector<int> a){
  if(a.size() == 0)
    return;
  else{
    for(int i = 0; i < a.size(); i++)
      cout << a[i] << '\t';
  }
  cout << endl;
}

// Print the union of 2 sorted arrays with duplicates
void printUnion(int *a, int aSize, int *b, int bSize){
  if(aSize == 0 && bSize == 0)
    return;
  else{

    vector<int> unionVector;

    int i = 0;
    int j = 0;
    int last = 0;

    // insert the smaller of first element regardless
    if(a[i] < b[j]){
      unionVector.push_back(a[i]);
      i++;
    }
    else if (b[j] < a[i]){
      unionVector.push_back(b[j]);
      j++;
    }
    else{// both are equal numbers 
      unionVector.push_back(a[i]);
      i++;
      j++;
    }

    // now traverse both the loops one increment at a time
    while(i < aSize && j < bSize){
      last = unionVector[unionVector.size() - 1];

      if(a[i] < b[j]){
        if(last != a[i])
          unionVector.push_back(a[i]);
        i++; // increment i in either case
      }
      else if(b[j] < a[i]){
        if(last != b[j])
          unionVector.push_back(b[j]);
        j++;
      }
      else{
        // both of the numbers are equal
        if(last != a[i])
          unionVector.push_back(a[i]);
        i++;
        j++;
      }
    }

    // lets say if 1 array wasn't complete
    while(i < aSize){
      last = unionVector[unionVector.size() - 1];

      if(last != a[i])
        unionVector.push_back(a[i]);
      i++;
    }

    while(j < bSize){
      last = unionVector[unionVector.size() - 1];

      if(last != b[i])
        unionVector.push_back(b[j]);
      j++;
    }

    printVector(unionVector);
  }
}

int main(){
  int a[] = {1,3,3,4,4,4,5,7};
  int b[] = {1,3,3,3,5,5,5,6,7,7,8,9};

  printUnion(a,8,b,12);

  return 0;
}
#包括
#包括
使用名称空间std;
//打印向量的内容
无效打印向量(向量a){
如果(a.size()==0)
返回;
否则{
对于(int i=0;icout如果两个数组都已排序,则只需提前跳过一个迭代器或另一个迭代器,或者如果存在匹配项,则跳过两个迭代器即可

比如:

void printUnion(int* a, int aSize, int* b, int bSize)
{
    int *aEnd = a + aSize, *bEnd = b + bSize;
    std::vector<int> unionVec;

    for (; a != aEnd; ) {
        if (b == bEnd) {
            // copy all of a
            while (a != aEnd) {
                unionVec.push_back(*a);
                a = std::upper_bound(a + 1, aEnd, *a);
            }
            break;
        }

        if (*b < *a) {
            unionVec.push_back(*b);
            b = std::upper_bound(b + 1, bEnd, *b);
        } 
        else {
            unionVec.push_back(*a);
            if (*b == *a) {
                b = std::upper_bound(b + 1, bEnd, *b);
            }
            a = std::upper_bound(a + 1, aEnd, *a);
        }
    }

    // copy all of b
    while (b != bEnd) {
        unionVec.push_back(*b);
        b = std::upper_bound(b + 1, bEnd, *b);
    }

    printVector(unionVec);
}
或非二进制搜索版本:

int* upper_bound(int* first, int* last, const int value) {
    for (; first < last && *first == value; ++first) {
        ;
    }

    return first;
}
int*上界(int*first,int*last,const int值){
对于(;first
这显然非常冗长,这就是为什么标准直接为您提供了一个算法:

void printUnion(int*a、int-aSize、int*b、int-bSize)
{
std::vector unionVec;
//加入工会
std::set_union(a,a+aSize,b,b+bSize,std::back_inserter(unionVec));
//除去重复
unionVec.erase(std::unique(unionVec.begin()、unionVec.end()、unionVec.end());
printVector(unionVec);
}

如果两个数组都已排序,则只需提前跳过一个迭代器或另一个迭代器,或者如果存在匹配项,则跳过这两个迭代器即可

比如:

void printUnion(int* a, int aSize, int* b, int bSize)
{
    int *aEnd = a + aSize, *bEnd = b + bSize;
    std::vector<int> unionVec;

    for (; a != aEnd; ) {
        if (b == bEnd) {
            // copy all of a
            while (a != aEnd) {
                unionVec.push_back(*a);
                a = std::upper_bound(a + 1, aEnd, *a);
            }
            break;
        }

        if (*b < *a) {
            unionVec.push_back(*b);
            b = std::upper_bound(b + 1, bEnd, *b);
        } 
        else {
            unionVec.push_back(*a);
            if (*b == *a) {
                b = std::upper_bound(b + 1, bEnd, *b);
            }
            a = std::upper_bound(a + 1, aEnd, *a);
        }
    }

    // copy all of b
    while (b != bEnd) {
        unionVec.push_back(*b);
        b = std::upper_bound(b + 1, bEnd, *b);
    }

    printVector(unionVec);
}
或非二进制搜索版本:

int* upper_bound(int* first, int* last, const int value) {
    for (; first < last && *first == value; ++first) {
        ;
    }

    return first;
}
int*上界(int*first,int*last,const int值){
对于(;first
这显然非常冗长,这就是为什么标准直接为您提供了一个算法:

void printUnion(int*a、int-aSize、int*b、int-bSize)
{
std::vector unionVec;
//加入工会
std::set_union(a,a+aSize,b,b+bSize,std::back_inserter(unionVec));
//除去重复
unionVec.erase(std::unique(unionVec.begin()、unionVec.end()、unionVec.end());
printVector(unionVec);
}

如果两个数组都已排序,则只需提前跳过一个迭代器或另一个迭代器,或者如果存在匹配项,则跳过这两个迭代器即可

比如:

void printUnion(int* a, int aSize, int* b, int bSize)
{
    int *aEnd = a + aSize, *bEnd = b + bSize;
    std::vector<int> unionVec;

    for (; a != aEnd; ) {
        if (b == bEnd) {
            // copy all of a
            while (a != aEnd) {
                unionVec.push_back(*a);
                a = std::upper_bound(a + 1, aEnd, *a);
            }
            break;
        }

        if (*b < *a) {
            unionVec.push_back(*b);
            b = std::upper_bound(b + 1, bEnd, *b);
        } 
        else {
            unionVec.push_back(*a);
            if (*b == *a) {
                b = std::upper_bound(b + 1, bEnd, *b);
            }
            a = std::upper_bound(a + 1, aEnd, *a);
        }
    }

    // copy all of b
    while (b != bEnd) {
        unionVec.push_back(*b);
        b = std::upper_bound(b + 1, bEnd, *b);
    }

    printVector(unionVec);
}
或非二进制搜索版本:

int* upper_bound(int* first, int* last, const int value) {
    for (; first < last && *first == value; ++first) {
        ;
    }

    return first;
}
int*上界(int*first,int*last,const int值){
对于(;first
这显然非常冗长,这就是为什么标准直接为您提供了一个算法:

void printUnion(int*a、int-aSize、int*b、int-bSize)
{
std::vector unionVec;
//加入工会
std::set_union(a,a+aSize,b,b+bSize,std::back_inserter(unionVec));
//除去重复
unionVec.erase(std::unique(unionVec.begin()、unionVec.end()、unionVec.end());
printVector(unionVec);
}

如果两个数组都已排序,则只需提前跳过一个迭代器或另一个迭代器,或者如果存在匹配项,则跳过这两个迭代器即可

比如:

void printUnion(int* a, int aSize, int* b, int bSize)
{
    int *aEnd = a + aSize, *bEnd = b + bSize;
    std::vector<int> unionVec;

    for (; a != aEnd; ) {
        if (b == bEnd) {
            // copy all of a
            while (a != aEnd) {
                unionVec.push_back(*a);
                a = std::upper_bound(a + 1, aEnd, *a);
            }
            break;
        }

        if (*b < *a) {
            unionVec.push_back(*b);
            b = std::upper_bound(b + 1, bEnd, *b);
        } 
        else {
            unionVec.push_back(*a);
            if (*b == *a) {
                b = std::upper_bound(b + 1, bEnd, *b);
            }
            a = std::upper_bound(a + 1, aEnd, *a);
        }
    }

    // copy all of b
    while (b != bEnd) {
        unionVec.push_back(*b);
        b = std::upper_bound(b + 1, bEnd, *b);
    }

    printVector(unionVec);
}
或非二进制搜索版本:

int* upper_bound(int* first, int* last, const int value) {
    for (; first < last && *first == value; ++first) {
        ;
    }

    return first;
}
int*上界(int*first,int*last,const int值){
对于(;first
这显然非常冗长,这就是为什么标准直接为您提供了一个算法:

void printUnion(int*a、int-aSize、int*b、int-bSize)
{
std::vector unionVec;
//加入工会
std::set_union(a,a+aSize,b,b+bSize,std::back_inserter(unionVec));
//除去重复
unionVec.erase(std::unique(unionVec.begin()、unionVec.end()、unionVec.end());
printVector(unionVec);
}

这里有一种方法。优雅可能会有所不同

void printUnion(int* a, int aSize, int* b, int bSize)
{
    std::multiset<int> x;
    x.insert(a, a + aSize);
    x.insert(b, b + bSize);

    for (auto y : x )
        cout << y << ",";
    cout << endl;
}
void printUnion(int*a、int-aSize、int*b、int-bSize)
{
std::多集x;
x、 插入(a,a+aSize);
x、 插入(b,b+b尺寸);
用于(自动y:x)

cout这里有一个方法。优雅可能会有所不同

void printUnion(int* a, int aSize, int* b, int bSize)
{
    std::multiset<int> x;
    x.insert(a, a + aSize);
    x.insert(b, b + bSize);

    for (auto y : x )
        cout << y << ",";
    cout << endl;
}
void printUnion(int*a、int-aSize、int*b、int-bSize)
{
std::多集x;
x、 插入(a,a+aSize);
x、 插入(b,b+b尺寸);
用于(自动y:x)

cout这里有一个方法。优雅可能会有所不同

void printUnion(int* a, int aSize, int* b, int bSize)
{
    std::multiset<int> x;
    x.insert(a, a + aSize);
    x.insert(b, b + bSize);

    for (auto y : x )
        cout << y << ",";
    cout << endl;
}
void printUnion(int*a、int-aSize、int*b、int-bSize)
{
std::多集x;
x、 插入(a,a+aSize);
x、 插入(b,b+b尺寸);
用于(自动y:x)

cout这里有一个方法。优雅可能会有所不同

void printUnion(int* a, int aSize, int* b, int bSize)
{
    std::multiset<int> x;
    x.insert(a, a + aSize);
    x.insert(b, b + bSize);

    for (auto y : x )
        cout << y << ",";
    cout << endl;
}
void printUnion(int*a、int-aSize、int*b、int-bSize)
{
std::多集x;
x、 插入(a,a+aSize);
x、 插入(b,b+b尺寸);
用于(自动y:x)

你能有效地使用合并排序的合并阶段,但忽略重复项吗?这可能会使你的算法更简单,因为它至少对我来说有点复杂。将两个数组复制到一个
std::set
?@ThomasMatthews我怀疑这是家庭作业代码。如果你想要“最优雅的”,那么算法
std::set_union
的实现方式如何呢?嘿,伙计们,谢谢你们的回答!这是一个面试问题,所以我恐怕不能使用内置函数。请检查我的编辑,了解更多关于这一点的信息。谢谢!你们实际上想要合并排序的合并阶段,但忽略重复项。这可能会使你们的算法成为一个问题简单一点,至少对我来说有点复杂。将两个数组复制到
std::set
?@ThomasMatthews我怀疑这是家庭作业代码。如果你想要“最优雅”,那么算法
std::set_union
的实现方式如何呢?嘿,伙计们,谢谢你们的回答!这是一个面试问题,所以我恐怕不能使用内置函数。请检查我的编辑,了解更多关于这一点的信息。谢谢!你们实际上想要合并排序的合并阶段,但忽略重复项。这可能会使你们的算法成为一个问题简单一点,至少对我来说有点复杂。将两个数组复制到
std::set
?@Thoma