-2

I am trying to write a function for creating a prime factors list. For this - I am using a recursive function. Here are the calls:

    private int Problem003()
    {
        //The prime factors of 13195 are 5, 7, 13 and 29.
        //What is the largest prime factor of the number 600851475143 ?

        return GeneratePrimeFactorsList(15).Last();
    }

    private List<int> GeneratePrimeFactorsList(int n)
    {
        List<int> _primefactors = new List<int>();
        _primefactors.Add(2);

        int i = 3;

        while(i <= n)
        {   
            if (CheckIfIntIsPrime(_primefactors, i))
            {   
                _primefactors.Add(i);
            }

            i=i+2;
        }

        return _primefactors;
    }

    private bool CheckIfIntIsPrime(List<int> _primefactors, int i)
    {   
        if (_primefactors.Count() == 0)
        {   
            return true;
        }
        else
        { 
            if(i % _primefactors.First() != 0)
            {
                _primefactors.Remove(_primefactors.First());
                return CheckIfIntIsPrime(_primefactors, i);
            }
            else
            {   
                return false;
            }
        }
    }

The problem is that, when I am calling for CheckIfIntIsPrime(List, i), which have bool return type - it modifies the List. That means, that after the check - the passed argument into the GeneratePrimeFactorsList(int) is getting empty after each while loop iteration.

The CheckIfPrime function works correctly, but modifies the passed argument, when it should not - I dont relate them.

Very strange case, but I feel, that I missing knowledge about some of the List properties.

Egor Osaulenko
  • 87
  • 1
  • 12
  • 2
    The code as is would lead to infinite recursion. – Ondrej Tucny Oct 25 '16 at 18:56
  • 1
    Non-primitive types are not copied. If you want to work on copy, preferably create local list from passed reference by calling `List local = new List(_primefactors);` – Tomasz Plaskota Oct 25 '16 at 18:56
  • @OndrejTucny dont agree - code does not fall into infinte loop. – Egor Osaulenko Oct 25 '16 at 18:58
  • `if (_primefactors.Count() == 0)` should always be false as you never remove anything from the list. – 001 Oct 25 '16 at 18:58
  • @EgorOsaulenko In case that `_primefactors.Count() != 0 && i % _primefactors.First() != 0` is satisfied then it **does**. Your core is unfortunatelly quite unclear and the recursion seems completely unnecessary. – Ondrej Tucny Oct 25 '16 at 19:01
  • Gentlemen - my bad, updated the code. – Egor Osaulenko Oct 25 '16 at 19:01
  • 2
    [Are ILists passed by value?](http://stackoverflow.com/questions/2324790/are-ilists-passed-by-value) – 001 Oct 25 '16 at 19:06
  • I don't follow what you are trying to do. First of all your recursive call will never stop (i.e. StackOverflow). You keep referring to Prime factorization in the function names, but seems like you are checking if a given number is a prime number or not. – Vikhram Oct 25 '16 at 19:09
  • @JohnnyMopp thank you, found the answer out there, just had to replace the call from CheckIfIntIsPrime(_primefactors, i) to CheckIfIntIsPrime(new List(_primefactors), i). If you will post it as an answer - I will accept it. – Egor Osaulenko Oct 25 '16 at 19:17
  • @Vikhram it does not mater, what are the names of the functions. As I said - I had a problem with understanding, why passed argument is getting modified in initial function. Johnny Mopp understanded me correctly and a gave a precise answer. – Egor Osaulenko Oct 25 '16 at 19:29

1 Answers1

1

An object is a reference type. All variables that are typed as a reference type don't contain the value itself; they each contain a reference or pointer to the value (or object). This is true even when the variable is passed as a parameter.

The function that receives the object parameter is not capable of modifying the variable itself (which, again, is just a pointer). This means it cannot cause the variable to point somewhere else. However, it can use the pointer to get a reference to the object and modify the object itself.

If you want to pass an object but want to make absolutely sure it doesn't get modified, you can pass a clone of it.

Community
  • 1
  • 1
John Wu
  • 50,556
  • 8
  • 44
  • 80