c#程序冻结整数列表

时间:2018-04-02 01:15:47

标签: c# list integer initialization factors

当我运行我的程序时,我会初始化一个整数列表并冻结。我知道这是因为Console.WriteLine();列表初始化后的方法不会出现在控制台上。当我运行它时,唯一的输出是“在列表之前”。我错过了什么?我真的希望这不是很明显和令人尴尬。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Euler._1_50
{
    class Challenge3
    {
        public Challenge3()
        {
            Console.WriteLine("before list");

            long num = 600_851_475_143;
            long high = 0;
            long length = 0;
            List<int> factr = new List<int>();

            Console.WriteLine(IsPrime(num));
            Console.WriteLine("after list");

            for (long i = 2; i <= num / 2; i++)
            {
                if (IsPrime(i) && num / i == 0)
                {
                    num = num / i;
                    factr.Add((int)i);
                    length++;
                }
            }

            for (long i = 0; i <= length; i++)
            {
                if (i > high) high = i;
            }

            Console.WriteLine(high);

        }

        private bool IsPrime(long i)
        {
            bool isPrime = false;

            for (long j = 2; j <= i/2; j++)
            {
                if (i % j == 0) isPrime = false;
                else isPrime = true;
            }
            return isPrime;
        }
    }
}

3 个答案:

答案 0 :(得分:4)

IsPrime将至少运行3000亿次迭代,这就是锁定的原因。

整数的素因子永远不会大于该整数的平方根。

此外,一旦确定了数字为素数,您就不需要继续检查。

因此,请考虑将测试循环更改为:

private bool IsPrime(long i)
{
    long upper = (long)Math.Sqrt(i);
    for (long j = 2; j <= upper; j++)
    {
        if (i % j == 0)
           return false;
    }
    return true;
}

最后,关于'high'的最后一段代码建议你打算在更大的代码中使用它。如果是这种情况,最好先预先计算哪些数字是素数,然后将它们存储在List或HashSet中以便快速重复使用。

答案 1 :(得分:2)

不是挂起的List<T>构造函数。它以IsPrime作为参数调用600_851_475_143。随着循环运行一半,它进行了3000亿次迭代。这需要时间。

即使你等待它返回下一个循环运行IsPrime,所有整数都在2到300亿之间。这需要更长时间才能完成。它需要超过90万亿次迭代的最内层循环!

它并不是100%清楚你要做的事情,但是你应该考虑一个不同的算法,因为无论你如何编码,这个算法都会非常慢。

答案 2 :(得分:0)

所以我正在做项目欧拉问题。在我做这个之前的一天,我设法做了一个涂料素数发现算法,但我太懒了,不能把它变成第一篇文章中看到的主要因子问题。经过又一天拒绝回答和讨厌生活,我终于写了一个更好的计划。我现在可以在大约半秒内找到答案。可能更干净,但它完成了我需要它完成。 #sosatisfying

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Euler._1_50
{
    class Challenge3_1
    {
        List<long> primes = new List<long>();
        List<bool> isPrime = new List<bool>();
        List<int> factors = new List<int>();

        long primeNums = 0;
        long bigNum = 600_851_475_143;
        int primeBnds = 1_000_000;

        public Challenge3_1()
        {
            genList();
            getPrimes();
            //listPrimes();
            factor();

            Console.WriteLine("final");
            listFactors();
        }


        //not currently being used
        private void genList()
        {
            for (int i = 0; i <= primeBnds; i++)
            {
                isPrime.Add(true);
            }
        }

        private void getPrimes()
        {
            isPrime[0] = false;
            isPrime[1] = false;

            for (int i = 2; i <= primeBnds; i++)
            {
                if (isPrime[i] == true)
                {
                    for (int j = i, index = 0; index <= primeBnds; index += j)
                    {
                        if (j < index)
                        {
                            isPrime[index] = false;
                        }
                    }
                }
            }
        }

        private void factor()
        {
            long temp = bigNum;

            for (int i = 2; i <= primeBnds;)
            {
                if (isPrime[i] == true && temp % i == 0)
                {
                    temp = temp / i;
                    factors.Add(i);
                    Console.WriteLine(i);
                }

                if (temp % i != 0)
                {
                    i++;
                }

                //if (factors.Capacity != 0) listFactors();
            }

        }

        private void listPrimes()
        {
            for (int i = 0; i <= primeBnds; i++)
            {
                if (isPrime[i] == true)
                {
                    Console.WriteLine(++primeNums + " " + i);
                }
            }
        }

        private void listFactors()
        {
            for (int i = 0; i < factors.Capacity; i++)
            {
                Console.Write(factors[i] + " ");
            }
        }

    }
}