这是我从Project获得问题3的解决方案。有没有办法提高解决方案的效率?
int largestPrimeFactor(unsigned _int64 x)
{
unsigned __int64 remainder = x;
int max_prime;
for (int i = 2; i <= remainder; i++)
{
while(remainder%i==0) {
remainder /= i;
max_prime = i;
}
}
return max_prime;
}更新:感谢大家的建议。在此基础上,我对算法进行了如下修改:
1)跳过甚至是候选区长。
while(remainder%2==0) {
max_prime = 2;
remainder /= 2;
}
for (int i = 3; i <= remainder; i += 2)
{
while(remainder%i==0) {
max_prime = i;
remainder /= i;
}
}2)求出余数的平方根。
for (int i = 2; i*i <= remainder; i++)
{
while(remainder%i==0) {
max_prime = i;
remainder /= i;
cout << i << " " << remainder << endl;
}
}
if (remainder > 1) max_prime = remainder;3)利用埃拉托斯提尼筛算法预先生成素数。在这个简单的例子中可能不值得。
发布于 2013-04-26 22:26:36
发布于 2013-04-26 23:41:36
好的,这是我的看法。希望它可能有用(编辑:不要引发“不要使用前导下划线”注释-添加了一个名称空间)。编辑#2:添加了一个更快的函数get_factor_prime_faster()和一个辅助函数。最后参见有关速度测试的说明。
#include <cstdint>
#include <iostream>
namespace so
{
// Head-on approach: get_factor_prime()
std::uint64_t get_factor_prime( std::uint64_t _number )
{
for( std::uint64_t i_ = 2; i_ * i_ <= _number; ++i_ )
if( _number % i_ == 0 )
return ( get_factor_prime( _number / i_ ) );
return ( _number );
}
// Slightly improved approach: get_factor_prime_faster() and detail::get_factor_prime_odd()
namespace detail
{
std::uint64_t get_factor_prime_odd( std::uint64_t _number )
{
for( std::uint64_t i_ = 3; i_ * i_ <= _number; i_ += 2 )
if( _number % i_ == 0 )
return ( get_factor_prime_odd( _number / i_ ) );
return ( _number );
}
} // namespace so::detail
std::uint64_t get_factor_prime_faster( std::uint64_t _number )
{
while( _number % 2 == 0 )
_number /= 2;
return ( detail::get_factor_prime_odd( _number ) );
}
} // namespace so
int main()
{
std::cout << so::get_factor_prime( 600851475143 ) << std::endl;
std::cout << so::get_factor_prime( 13195 ) << std::endl;
std::cout << so::get_factor_prime( 101 ) << std::endl;
std::cout << so::get_factor_prime_faster( 600851475143 ) << std::endl;
std::cout << so::get_factor_prime_faster( 13195 ) << std::endl;
std::cout << so::get_factor_prime_faster( 101 ) << std::endl;
return( 0 );
}程序输出:
6857
29
101
6857
29
101诚然,我仍然想不出如何轻易地检查一个数字是否是素数.
编辑:在一个循环测试的600851475143 * 1024号码,GCC 4.7.2与-O3,Linux,英特尔i5核心。时间如下(约):
get_factor_prime比OP的解决方案快3一倍;
get_factor_prime_faster比OP的解决方案快6一倍。
https://stackoverflow.com/questions/16245976
复制相似问题