Project Euler 3 (performance)

Project Euler 3 (performance)

本文关键字:performance Euler Project      更新时间:2023-10-16

这是我在Project Euler中对问题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( 使用埃拉托斯特内斯筛算法提前生成素数。在这个简单的例子中可能不值得。

好的,这是我对它的看法。希望它可能有用(编辑:不要引发"不要使用前导下划线"的评论-添加了一个命名空间(。编辑#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、Intel i5 Core进行循环测试。时间如下(大约(:

get_factor_prime比OP的解快3倍;

get_factor_prime_faster比OP的解决方案快6倍。

一种常见的方法:

步骤1:使用埃拉托斯特内斯筛算法生成高达ceil的素数(sqrt(number((
第二步:用这些来计算数字。