简体   繁体   中英

c# program freezes on list of integers

When I run my program it gets to the point were I initialize a list of integers and it freezes. I know this because the Console.WriteLine(); methods after the list initialization don't appear on the console. When I run it, the only output is "before list". What am I missing? I really hope it's not obvious and embarrassing.

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;
        }
    }
}

IsPrime is going to be running at least 300 billion iterations, which is why it is locking.

The prime factors of an integer will never be larger than the square root of that integer.

Additionally, once you've determined the number to be prime, you don't need to keep checking.

So consider changing your test loop to:

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;
}

Finally, the last chunk of code about 'high' suggests you intend on using this in a larger piece of code. If that's the case, you are better off precalculating which numbers are primes once and storing them in a List or HashSet for fast repeated use.

It's not the List<T> constructor that's hanging. It's IsPrime called with 600_851_475_143 as an argument. With the loop running to half that it's 300 billion iterations. It's going to take time.

And even if you wait for it to return the next loop runs IsPrime for all integers between 2 and that same 300 billions. This will need even longer to complete. It requires over 90 trillion iterations of the inner-most loop!

It's not 100% clear what you're trying to do, but you should think about a different algorithm because this one will run very slow no matter how you code it.

So I'm doing Project Euler questions. I managed to make a dope prime finding algorithm a day before I did this, but I was too lazy to right it into the prime factoring question seen in the first post. After another day of refusing to look up answers and hating life, I finally wrote a better program. I can now find the answer in about half a second. Could probably be cleaner, but it got done what I need it to get done. #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] + " ");
            }
        }

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM