我通过解决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);
}
}
答案 0 :(得分:3)
C ++中的数组具有固定的大小,因此每次连接时都必须动态创建一个新数组,并且必须记住delete
旧的数组。
所以我建议只使用vectors。
已经有a question on concatenating vectors,其完成如下:
vector1.insert( vector1.end(), vector2.begin(), vector2.end() );
答案 1 :(得分:2)
这里有多种可能性。由于您只对返回一对数字感兴趣,因此可以返回std :: pair。你需要
#include <utility>
return {primeFactorDivL, primeFactorDivR};
最后一点依赖于c ++ 11的功能,因此您必须确保为您的编译器启用了此功能。在早期的C ++中,您可以return std::make_pair(primeFactorDivL, primeFactorDivR)
代替。