使用迭代器解决数组求和问题并仅测试相等性

时间:2010-07-27 18:00:25

标签: c++ iterator

在准备采访时,我决定使用迭代器逻辑编写经典的“查找数组中有两个元素总结到给定数字”的问题,以便它可以推广到除{{之外的其他容器。 1}}。

到目前为止,这是我的功能

vector

当然,这不起作用,但如果不使用条件// Search given container for two elements with given sum. // If two such elements exist, return true and the iterators // pointing to the elements. bool hasElementSum( int sum, const vector<int>& v, vector<int>::iterator& el1, vector<int>::iterator& el2 ) { bool ret = false; el1 = v.begin(); el2 = v.end()-1; while ( el1 != el2 ) { if ( *el1 + *el2 == sum ) return true; ++el1;--el2; } return false; } ,我无法找到方法。我看来建议不要使用omnly对迭代器进行等式检查,以便能够推广到支持迭代器的所有类型的容器。

谢谢!

5 个答案:

答案 0 :(得分:5)

首先,你的算法是错误的,除非你提前确定你只需要查看一个项目在集合的前半部分中的总和,另一个是收藏的后半部分。

如果输入没有排序,那么@ sbi的回答就差不多了。

使用排序的随机访问输入,您可以从第一个元素开始,并进行二分搜索(或插值搜索等)以查看是否可以找到必须使用的值来生成期望的总和。然后你可以尝试第二个元素,但是当你进行二分搜索(或其他)时,使用前一个搜索的结果作为上限。由于您的第一个元素大于前一个元素,因此产生正确总和的匹配值必须小于或等于您上次找到的值。

答案 1 :(得分:3)

foreach element1 in array
  foreach element2 in array + &element1
    if( element1 + element2 == sum )
      return true
return false

这是O(N ^ 2),因为你必须将每个元素添加到每个其他元素。

答案 2 :(得分:2)

通常不会通过排序数组询问这个问题吗? 如果不是,它必须以O(n ^ 2)复杂度工作,并且你必须检查所有可能的对。

答案 3 :(得分:0)

我建议使用以下方法但不分析顺序

使用向量的所有元素构造二元搜索树,然后为每个元素构建

foreach(element = vec.begin to vec.end)
{
    if element == node.data, skip

    if the element + node.data == sum, return true

    if the element + node.data > sum, goto left child

    if the element + node.data < sum, goto right child
}

不是一个完美的解决方案/算法,但这类似的东西。

答案 4 :(得分:0)

抱歉,我搞砸了这个。我打算写的是一种线性传递后的线性传递,这是给出这个问题的典型答案,正如ltsik在他对Jerry的评论中指出的那样,即

bool hasElementSum( int sum, const vector<int>& v, int* ind1, int* ind2 )
{

    *ind1 = 0; *ind2 = v.size()-1;

    std::sort( v.begin(), v.end() );

    while ( *ind1 <= *ind2 ) {
        int s = v[*ind1] + v[*ind2];
        if ( s > sum ) (*ind1)++;
        else if ( s < sum ) (*ind2)++;
        else return true
    }
    return false;
}

我的问题是如何使用迭代器来编写它而不说while (iter1 <= iter2 )以便通用,但我现在看到这没有意义,因为这个算法无论如何都需要随机访问迭代器。此外,返回索引是没有意义的,因为它们引用已排序的数组而不是原始数组。