C# Project Euler问题3帮助

C# Project Euler问题3帮助,c#,algorithm,language-agnostic,primes,C#,Algorithm,Language Agnostic,Primes,我正在努力完成Euler项目,在问题03上遇到了障碍。我有一个适用于较小数字的算法,但问题3使用了一个非常非常大的数字 问题03: 13195的主要因子为5、7、13和29。 数字600851475143中最大的素因子是什么 这是我的C#解决方案,它已经运行了将近一个小时。我不是在寻找答案,因为我确实想自己解决这个问题。主要是寻求帮助 static void Main(string[] args) { const long n = 600851475143;

我正在努力完成Euler项目,在问题03上遇到了障碍。我有一个适用于较小数字的算法,但问题3使用了一个非常非常大的数字

问题03: 13195的主要因子为5、7、13和29。 数字600851475143中最大的素因子是什么

这是我的C#解决方案,它已经运行了将近一个小时。我不是在寻找答案,因为我确实想自己解决这个问题。主要是寻求帮助

    static void Main(string[] args) {
        const long n = 600851475143;
        //const long n = 13195;
        long count, half, largestPrime = 0;
        bool IsAPrime;

        half = n / 2;

        for (long i = half; i > 1 && largestPrime == 0; i--) {
             if (n % i == 0) { // these are factors of n
                count = 1;
                IsAPrime = true;
                while (++count < i && IsAPrime) {
                    if (i % count == 0) { // does a factor of n have a factor? (not prime)
                        IsAPrime = false;
                    }
                }
                if (IsAPrime) {
                    largestPrime = i;
                }
            }
        }

        Console.WriteLine("The largest prime factor is " + largestPrime.ToString() + ".");
        Console.ReadLine();
    }
static void Main(字符串[]args){
常数长n=600851475143;
//常数长n=13195;
长计数,一半,最大素数=0;
布尔·伊萨普里姆;
一半=n/2;
对于(长i=half;i>1&&largestPrime==0;i--){
如果(n%i==0){//这些是n的因子
计数=1;
IsAPrime=true;
while(++count
首先,不要从n/2开始搜索,而是从n的平方根开始搜索。你会得到一半的因子,另一半是它们的补充

例如:


你需要减少你正在做的检查量。。。想想你需要测试哪些数字


要获得更好的方法,请阅读。。。它会让你指向正确的方向。

试着用测试来测试一个素数。这应该会大大加快速度。

尽管这个问题要求的是最大的素数因子,但这并不一定意味着你必须先找到一个…

实际上,在这种情况下,你不需要检查素数,只需删除你找到的因子即可。从n==2开始,向上扫描。当邪恶大数%n==0时,将邪恶大数除以n并继续使用较小的邪恶数。当n>=sqrt(大邪恶数)时停止


在任何现代机器上都不应超过几秒钟。

至于接受nicf回答的原因:

对于Euler的问题,这是可以的,但在一般情况下,这并不是一个有效的解决方案。为什么要用偶数作为因子

  • 如果n为偶数,则向左移动(除以 2) 直到它不再是。如果是 那么,2是最大的素数 因素
  • 如果n不是偶数,则不必这样做 测试偶数
  • 的确,你可以在 sqrt(n)
  • 你只需要测试素数就可以了 因素。测试可能会更快 k是否除以n,然后测试它 不过是为了首要性
  • 您可以优化上的上限 当你找到一个因素时,苍蝇就会飞起来
这将导致出现如下代码:

n = abs(number);
result = 1;
if (n mod 2 = 0) {
  result = 2;
  while (n mod 2 = 0) n /= 2;
}
for(i=3; i<sqrt(n); i+=2) {
  if (n mod i = 0) {
    result = i;
    while (n mod i = 0)  n /= i;
  }
}
return max(n,result)
n=abs(编号);
结果=1;
如果(n模2=0){
结果=2;
而(n模2=0)n/=2;
}

对于(i=3;i另一种方法是首先得到n/2以下的所有素数,然后检查模数是否为0。
可以找到一个算法,我用它来获取所有小于等于n的素数。

在Java中使用递归算法运行不到一秒钟……仔细想想你的算法,因为它包含一些“暴力强制”这是可以消除的。还可以看看如何通过中间计算减少解空间。

我这样做的方式是搜索素数(
p
),从2开始使用Eratosthenes筛。该算法可以在中找到1000万以下的所有素数。所有Project Euler的问题都需要不到一分钟的时间;即使是Python中未优化的递归实现也需要不到一秒钟的时间[0.09秒(cpu 4.3GHz)]

从数学导入sqrt
def最大_因数(数字):

对于范围内的除数(2,int(sqrt(number)+1.5)):#除数您可能希望看到:

我喜欢lill mud的解决方案:

需要“mathn.rb”
将600851475143.prime_division.last.first放在第一位

我查过了


这应该足够快…注意,不需要检查素数…

找到答案后,在浏览器中输入以下内容;)

Wofram Alpha是您的朋友

C++中的Easy peasy:

#include <iostream>

using namespace std;


int main()
{
    unsigned long long int largefactor = 600851475143;
    for(int i = 2;;)
    {
        if (largefactor <= i)
            break;
        if (largefactor % i == 0)
        {
            largefactor = largefactor / i;
        }
        else
            i++;
    }

    cout << largefactor << endl;

    cin.get();
    return 0;
}
#包括
使用名称空间std;
int main()
{
无符号长整型大系数=600851475143;
对于(int i=2;;)
{

如果(大因子< P>)C++上的这个解在我的英特尔四核I5 IMAC(3.1 GHz)

上取了3.7毫秒。
#包括
#包括
#包括
使用std::sqrt;使用std::cin;
使用std::cout;使用std::endl;
长lpf(长n)
{
长启动=(sqrt(n)+2%2);
如果(开始%2==0)开始++;
for(长i=开始;i!=2;i-=2)
{
如果(n%i==0)//那么i是n的一个因子
{
长j=2L;
做{
++j;
}
而(i%j!=0&&j n;//600851475143L
开始、结束的时间;
时间(&开始);
int i;
对于(i=0;i!=3000;++i)
ans=lpf(n);
时间(&结束);

cout也许这被认为是作弊,但haskell中的一种可能性是写作(记录在案,我自己写了这些行,没有检查eulerproject线程)


我将起点改为:startAt=(long)Math.Floor(Math.Sqrt(n));这给了我一个直接的答案。谢谢!这个方法可以找到数字的因子,但它将同时包含素数和非素数。例如9不是素数。一旦你找到3,你就设置n=n/3=9,然后从那里重复。@Jim:是的,这将是问题的第一部分。要找到素数因子,你还必须找到因子。不过,我想你可以在另一天做
from math import sqrt

def largest_primefactor(number):
    for divisor in range(2, int(sqrt(number) + 1.5)): # divisor <= sqrt(n)
        q, r = divmod(number, divisor)
        if r == 0:
            #assert(isprime(divisor))
            # recursion depth == number of prime factors,
            # e.g. 4 has two prime factors: {2,2}
            return largest_primefactor(q) 

    return number # number is a prime itself
long n = 600851475143L; //not even, so 2 wont be a factor
int factor = 3; 
while( n > 1)
{
    if(n % factor == 0)
    {
        n/=factor;
    }else
        factor += 2; //skip even numbrs
}
        print factor;
#include <iostream>

using namespace std;


int main()
{
    unsigned long long int largefactor = 600851475143;
    for(int i = 2;;)
    {
        if (largefactor <= i)
            break;
        if (largefactor % i == 0)
        {
            largefactor = largefactor / i;
        }
        else
            i++;
    }

    cout << largefactor << endl;

    cin.get();
    return 0;
}
#include <iostream>
#include <cmath>
#include <ctime>

using std::sqrt; using std::cin;
using std::cout; using std::endl;

long lpf(long n)
{
  long start = (sqrt(n) + 2 % 2);
  if(start % 2 == 0) start++;

  for(long i = start; i != 2; i -= 2)
    {
      if(n % i == 0) //then i is a factor of n                                                
        {
          long j = 2L;
          do {
              ++j;
             }
          while(i % j != 0 && j <= i);

          if(j == i) //then i is a prime number                                           
            return i;
        }
    }
}

int main()
{
  long n, ans;
  cout << "Please enter your number: ";
  cin >> n; //600851475143L                                                               

  time_t start, end;
  time(&start);
  int i;
  for(i = 0; i != 3000; ++i)
      ans = lpf(n);
  time(&end);

  cout << "The largest prime factor of your number is: " << ans << endl;
  cout << "Running time: " << 1000*difftime(end, start)/i << " ms." << endl;

  return 0;
}
import Data.Numbers.Primes
last (primeFactors 600851475143)