两个动态分配的数组的交集c ++

时间:2015-11-26 01:04:26

标签: c++ arrays function dynamic-arrays

我正在尝试创建一个函数,它将找到两个动态分配的数组的交集,将数组1与数组2进行比较。对于数组1中不在数组2中的任何值,应在数组1中删除这些值,以便数组1现在只保存两个数组的公共值(无重复)。我不能在我班级当前函数之外使用向量,哈希或任何其他东西:

到目前为止,这是我的代码:

bool IntSet::contains(int val) const
{
   for (int i = 0; i < numValues; i++)
{
    if (set[i] == val)
        return true;
}
return false;
}

此函数将整数参数与当前存储在数组中的值进行比较...如果数组中的值返回true,则返回false;

这个下一个函数接受一个值并从数组中删除该值:

void IntSet::remove(int val)
{
for (int i = 0; i < numValues; i++)
{
    if (set[i] == val)
        for (int j = 0; j < numValues; j++)
            set[j] = set[j + 1];
}
numValues--;
}

这里我遇到了问题,下一个函数应该遍历一个数组并将这些值与另一个数组中的值进行比较...如果一个数组中的一个值在另一个,它应该跳过它,但如果一个值不在调用该函数的数组中,它应该从调用数组中删除该值:

void IntSet::removeDifferent(const IntSet &set2)
{
  for (int i = 0; i < set2.size(); i++)
  {
    if (!set2.contains(set[i]))
    {
        remove(set[i]);
    }
  }
}

我已经在removeDifferent()函数上尝试了大约50种不同的变体,我似乎无法想象出这一点。有人能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:0)

您正在通过i的索引重复set2,但之后您正在测试set[i]。试试这个:

void IntSet::removeDifferent(const IntSet &set2)
{
    for (int i = 0; i < numValues; ) {
        if (!set2.contains(set[i])) {
            remove(set[i]);
        } else {
            i++;
    }
}

请注意,我还从i++循环标头中删除了for。这是因为当您删除元素时,所有以下元素都向下移动,因此下一个元素将在数组中占据一席之地。如果你增加i,它将跳过该元素。

您还需要修复remove。它应该从i开始它的内部循环,因此它只会在删除元素之后向下移动元素,它应该停在numValues-1,因此它不会尝试访问数组外部何时复制set[j+1]。作为优化,一旦找到匹配项,它就可以break从外部循环中出来(我假设IntSet不允许重复,因为您只将numValues递减1 )。

void IntSet::remove(int val)
{
    for (int i = 0; i < numValues; i++)
    {
        if (set[i] == val) {
            for (int j = i; j < numValues - 1; j++) {
                set[j] = set[j + 1];
            }
            break;
        }
    }
    numValues--;
}

答案 1 :(得分:0)

你的问题出在你的remove()函数中:

void IntSet::remove(int val)
{
for (int i = 0; i < numValues; i++)
{
    if (set[i] == val)
        for (int j = 0; j < numValues; j++)
            set[j] = set[j + 1];
}
numValues--;
}

你可以在这里使用纸和笔来弄清楚自己为什么会出错。从一个典型的例子开始:让我们说你找到了你在五元素数组的第三个元素中寻找的值:

if (set[i] == val)

在此示例中,i将设置为2,numValues将设置为5。 val是什么并不重要。无论是什么,你在i为2时发现它,numValues为5:你在五元素数组的第三个元素中找到它。记住这一点。

现在,您知道现在应该删除此五元素数组中的第三个元素。但你认为接下来会发生什么:

        for (int j = 0; j < numValues; j++)
            set[j] = set[j + 1];

好吧,使用上述纸和笔,如果你解决了,将会发生以下情况:

  • set [1]将被复制到设置[0]
  • set [2]将被复制到设置[1]
  • set [3]将被复制到set [2]
  • set [4]将被复制到set [3]
  • set [5]将被复制到set [4]

这里有两个问题:

A)没有set[5]。回想一下,这是一个五元素阵列,你只有set[0]set[4]

B)你不应该将数组中的所有内容复制到一个元素。您必须仅复制之后要删除的元素。

解决这两个问题,您可能会发现一切都能正常运行。