First of all: if the string length is n, you get 2 ^ n lines as output. So, if you want to process strings of length 70, you have a problem.
You can use a counter enumerating from 0 to 2 ^ n and treat it like a beaten mask: if the first bit is 1, you put a space between the first and second char, if it is zero, you do not.
Thus, an unsigned length of 64 is sufficient to process strings of length 65.
An example implementation without recursion (it is a bit more detailed than other examples), but should be much faster than other implementations for long inputs:
public IEnumerable<string> GetPartitionedStrings(string s) { if (s == null) yield break; if (s == "") { yield return ""; yield break; } if (s.Length > 63) throw new ArgumentOutOfRangeException("String too long..."); var arr = s.ToCharArray(); for(ulong i = 0, maxI = 1UL << (s.Length - 1); i < maxI; i++) { yield return PutSpaces(arr, i); } } public string PutSpaces(char[] arr, ulong spacesPositions) { var sb = new StringBuilder(arr.Length * 2); sb.Append(arr[0]); ulong l = 1; for (int i = 1; i < arr.Length; i++, l <<= 1) { if ((spacesPositions & l) != 0UL) sb.Append(" "); sb.Append(arr[i]); } return sb.ToString(); }
You could probably get away with a bit field, but we are already in billions of lines, so I will try to reformulate the problem a bit.
A. Chiesa
source share