Given an alphabet and a non-negative integer n, generate all strings over that alphabet with length from 0 to n. The exact-length version is the core subproblem.
For alphabet "abc" and exact length 2, the result is:
The Java version uses depth-first search with backtracking. It follows one candidate string to the requested length before returning to explore the next branch. The up-to-length variant repeats the same fixed-length search across the requested range.
The Haskell version expresses the same enumeration as breadth-first expansion. It works level by level, expanding all partial candidates of the current length before moving to the next length. This contrasts with the Java implementation, which follows one branch at a time.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
-- generate strings with given length from the alphabet gen_len :: Int -> [Char] -> [String] gen_len n alphabet = gen_len' n [""] where gen_len' 0 acc = map reverse acc gen_len' n acc = gen_len' (n-1) $ concatMap (\es -> [(e:es) | e <- alphabet]) acc
-- generate strings with <= length from the alphabet gen_up_to_len :: Int -> [Char] -> [String] gen_up_to_len n alphabet = concat [gen_len i alphabet | i <- [0..n]]
main = do print $ gen_len 2"abc" print $ gen_up_to_len 2"abc" print $ length $ gen_up_to_len 3"abc"