用C ++连接和返回数组

时间:2016-07-03 20:30:22

标签: c++ arrays vector

我通过解决Euler项目中的问题来学习C ++。其中一个练习是找到最大的素数因子,我发现最快的解决方法是使用分而治之,使用以下代码片段:

long primeFactor1(long n);

long primeFactor(long n)
{
    long divisorR = findDivisor(n);
    long divisorL = n/divisorR;

    if (divisorR == n){
        return divisorR;
    }

    long primeFactorDivL = primeFactor1(divisorL);
    long primeFactorDivR = primeFactor1(divisorR);

    return std::max(primeFactorDivL,primeFactorDivR);
}

long primeFactor1(long n)
{
    std::cout << "Is "<<n<< " a prime? " << checkPrime(n) << std::endl;
    if (checkPrime(n)){
        return n;
    }
    else{
        return primeFactor(n);
    }
}

其中checkPrime是一个检查它的函数,数字是素数,findDivisor找到数字n的最小偶数除数。所以这个程序运行良好,即使对于问题中给出的数字也能立即给出和输出(至少可以说这是非常大的)。

然而,我的问题是,我希望转换程序以返回所有主要除数而不是最大的除数。这意味着我基本上必须改变:

return std::max(primeFactorDivL,primeFactorDivR);

代替连接两者的东西,并调整函数,使它们可以返回生成的数组。

在我来自的Matlab中,我只是将方括号放在s.t。

周围
[primeFactorDivL,primeFactorDivR]

在C ++中执行此操作的最佳(最好也是最简单)方法是什么?

更新:

我尝试使用向量来实现它,这可以在下面的代码中使用叶子上的类型转换看到。但是,尝试编译它我得到编译错误:

primeFactor.cpp:51:9: error: no viable conversion from 'typename
      enable_if<__is_forward_iterator<__wrap_iter<long *> >::value && is_constructible<value_type, typename
      iterator_traits<__wrap_iter<long *> >::reference>::value, iterator>::type' (aka
      'std::__1::__wrap_iter<long *>') to 'std::vector<long>'
  ...primeFactorDivL.insert( primeFactorDivL.end(), primeFactorDivR.begin(), primeFactorDivR.end() );
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:568:5: note: candidate constructor not
      viable: no known conversion from 'typename enable_if<__is_forward_iterator<__wrap_iter<long *>
      >::value && is_constructible<value_type, typename iterator_traits<__wrap_iter<long *>
      >::reference>::value, iterator>::type' (aka 'std::__1::__wrap_iter<long *>') to 'const
      std::__1::vector<long, std::__1::allocator<long> > &' for 1st argument
    vector(const vector& __x);
    ^
1 error generated.

我的代码现在在哪里:

std::vector<long> primeFactor1(long n);

std::vector<long> primeFactor(long n)
{
    long divisorR = findDivisor(n);
    long divisorL = n/divisorR;

    if (divisorR == n){
        return std::vector<long>(divisorR);
    }

    std::vector<long> primeFactorDivL( primeFactor1(divisorL) );
    std::vector<long> primeFactorDivR( primeFactor1(divisorR) );

    return primeFactorDivL.insert( primeFactorDivL.end(), primeFactorDivR.begin(), primeFactorDivR.end() );
}

std::vector<long> primeFactor1(long n)
{
    std::cout << "Is "<<n<< " a prime? " << checkPrime(n) << std::endl;
    if (checkPrime(n)){
        return std::vector<long>(n);
    }
    else{
        return primeFactor(n);
    }
}

2 个答案:

答案 0 :(得分:3)

C ++中的数组具有固定的大小,因此每次连接时都必须动态创建一个新数组,并且必须记住delete旧的数组。

所以我建议只使用vectors

已经有a question on concatenating vectors,其完成如下:

vector1.insert( vector1.end(), vector2.begin(), vector2.end() );

答案 1 :(得分:2)

这里有多种可能性。由于您只对返回一对数字感兴趣,因此可以返回std :: pair。你需要

  • #include <utility>
  • 将primeFactor的返回类型更改为std :: pair
  • 将return语句更改为return {primeFactorDivL, primeFactorDivR};

最后一点依赖于c ++ 11的功能,因此您必须确保为您的编译器启用了此功能。在早期的C ++中,您可以return std::make_pair(primeFactorDivL, primeFactorDivR)代替。