Home > Software engineering >  What is stopping this program from having an output
What is stopping this program from having an output

Time:02-02

I made this code to brute force anagrams by printing all possible permutables of the characters in a string, however there is no output. I do not need simplifications as I am a student still learning the basics, I just need help getting it to work this way so I can better understand it.

using System;
using System.Collections.Generic;


namespace anagramSolver
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter anagram:");
            string anagram = Console.ReadLine();
            string temp = "";

            List<string> storeStr = new List<string>(0);
            List<int> storeInt = new List<int>(0);

            //creates factorial number for anagram
            int factorial = 1;
            for (int i = anagram.Length; i > 0; i--)
            {
                factorial *= i;
            }



            while (storeStr.Count != factorial)
            {
                Random rnd = new Random();
                while(temp.Length != anagram.Length)
                {
                    int num = rnd.Next(anagram.Length - 1);
                    if (storeInt.Contains(num) == true)
                    {
                    }
                    else
                    {
                        storeInt.Add(num);
                        temp  = anagram[num];
                    } 
                }
                if (storeStr.Contains(temp) == true)
                {
                    temp = "";
                }
                else
                {
                    storeStr.Add(temp);
                    Console.WriteLine(temp, storeStr.Count);
                    temp = "";
                }

            }
        }
    }
}

edit: added temp reset after it is deemed contained by storeStr

CodePudding user response:

Two main issues causing infinite loop:

1)

As per Random.Next documentation, the parameter is the "exclusive" upper bound. This means, if you want a random number between 0 and anagram.Length - 1 included, you should use rnd.Next(anagram.Length);.

With rnd.Next(anagram.Length - 1), you'll never hit anagram.Length - 1.

2)

Even if you solve 1, only the first main iteration goes well.

storeInt is never reset. Meaning, after the first main iteration, it will have already all the numbers in it.

So, during the second iteration, you will always hit the case if (storeInt.Contains(num) == true), which does nothing and the inner loop will go on forever.

CodePudding user response:

Several issues here...

The expression rnd.Next(anagram.Length - 1) generates a value between 0 and anagram.Length - 2. For an input with two characters it will always return 0, so you'll never actually generate a full string. Remove the - 1 from it and you'll be fine.

Next, you're using a list to keep track of the character indices you've used already, but you never clear the list. You'll get one output (eventually, when the random number generator covers all the values) and then enter an infinite loop on the next generation pass. Clear storeInt after the generation loop to fix this.

While not a true infinite loop, creating a new instance of the random number generator each time will give you a lot of duplication. new Random() uses the current time as a seed value and you could potentially get through a ton of loops with each seed, generating exactly the same values until the time changes enough to change your random sequence. Create the random number generator once before you start your main loop.

And finally, your code doesn't handle repeated input letters. If the input is "aa" then there is only a single distinct output, but your code won't stop until it gets two. If the input was "aab" there are three distinct permutations ("aab", "aba", "baa") which is half of the expected results. You'll never reach your exit condition in this case. You could do it by keeping track of the indices you've used instead of the generated strings, it just makes it a bit more complex.

There are a few ways to generate permutations that are less error-prone. In general you should try to avoid "keep generating random garbage until I find the result I'm looking for" solutions. Think about how you personally would go about writing down the full list of permutations for 3, 4 or 5 inputs. What steps would you take? Think about how that would work in a computer program.

CodePudding user response:

this loop

           while(temp.Length != anagram.Length)
            {
                int num = rnd.Next(anagram.Length - 1);
                if (storeInt.Contains(num) == true)
                {
                }
                else
                {
                    storeInt.Add(num);
                    temp  = anagram[num];
                } 
            }

gets stuck.

once the number is in storeInt you never change storeStr, yet thats what you are testing for loop exit

  • Related