I'm building a list of strings that contains all permutations of 2-letter strings, for instance "aa" to "zz". This is what I have:
public List<string> SomeMethod(int NumberOfChars) {
for (var i = 0; i < 26; i++)
{
char character1 = (char)(i + 97);
var Letter1 = character1.ToString();
for (var j = 0; j < 26; j++)
{
char character2 = (char)(j + 97);
var Letter2 = character2.ToString();
string TheString = Letter1 + Letter2;
TheList.Add(TheString);
}
}
return TheList;
}
Basically, it's a loop inside a loop that combines characters from the alphabet. Now suppose I want to include NumberOfChars
as a parameter that determines the length of each string. For instance, if I pass in 2 it would return all 676 2-letter strings from "aa"
to "zz"
and if I pass in 3 it would return all 17,576 3-letter strings from "aaa"
to "zzz"
.
For the moment, the easiest way to do it would be to have two different methods, one that returns 2-letter strings with two nested loops and another one that returns 3-letter strings with 3 nested loops.
What's a cleaner way to do this?
Thanks.
Recursion has more expressive power than iterative looping constructs. I say this because a while loop is equivalent to a tail recursive function and recursive functions need not be tail recursive. Powerful constructs are usually a bad thing because they allow you to do things that are difficult to read.
Loops are very much not recursion. In fact, they are the prime example of the opposite mechanism: iteration. The point of recursion is that one element of processing calls another instance of itself. The loop control machinery merely jumps back to the point where it started.
Iteration and recursion can occur infinitely: An infinite loop occurs with iteration if the loop-continuation test never becomes false; infinite recursion occurs if the recursion step does not reduce the problem in a manner that converges on the base case.
If a recursion never reaches a base case, it will go on making recursive calls forever and the program will never terminate. This is known as infinite recursion, and it is generally not considered a good idea. In most programming environments, a program with an infinite recursion will not really run forever.
How about a method like this:
public IEnumerable<string> SomeMethod(int NumberOfChars)
{
if (NumberOfChars == 0)
{
yield return string.Empty;
}
else
{
for (var i = 'a'; i <= 'z'; i++)
{
foreach (var s in SomeMethod(NumberOfChars - 1))
{
yield return i + s;
}
}
}
}
And just for fun, here's another solution using Linq:
public IEnumerable<string> SomeMethod(int n)
{
var r = Enumerable.Range('a', 26).Select(x => ((char)x).ToString());
return (n > 1) ? r.SelectMany(x => SomeMethod(n - 1), (x, y) => x + y) : r;
}
Here's an alternative that uses a loop instead of recursion:
public static List<string> SomeMethod(int numberOfChars)
{
IEnumerable<string> results = new List<string> { "" };
for (int i = 0; i < numberOfChars; ++i)
results = from s in results
from c in Enumerable.Range('a', 26)
select s + (char)c;
return results.ToList();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With