This involves a decision between 0 to 2 outcomes at each step. The base cases are there are no more characters or none of them can be used. In the latter case, we backtrack to output the entire tree. We store the word
in memory like dynamic programming. This naturally leads to a recursive algorithm.
#include <stdlib.h> /* EXIT */
#include <stdio.h> /* (f)printf */
#include <errno.h> /* errno */
#include <string.h> /* strlen */
static char word[2000];
static size_t count;
static void recurse(const char *const str) {
/* Base case when it hits the end of the string. */
if(*str == '\0') { printf("%.*s\n", (int)count, word); return; }
/* Bad input. */
if(*str < '0' || *str > '9') { errno = ERANGE; return; }
/* Zero is not a valid start; backtrack without output. */
if(*str == '0') return;
/* Recurse with one digit. */
word[count++] = *str - '0' + 'a' - 1;
recurse(str + 1);
count--;
/* Maybe recurse with two digits. */
if((*str != '1' && *str != '2')
|| (*str == '1' && (str[1] < '0' || str[1] > '9'))
|| (*str == '2' && (str[1] < '0' || str[1] > '6'))) return;
word[count++] = (str[0] - '0') * 10 + str[1] - '0' + 'a' - 1;
recurse(str + 2);
count--;
}
int main(int argc, char **argv) {
if(argc != 2)
return fprintf(stderr, "Usage: a.out <number>\n"), EXIT_FAILURE;
if(strlen(argv[1]) > sizeof word)
return fprintf(stderr, "Too long.\n"), EXIT_FAILURE;
recurse(argv[1]);
return errno ? (perror("numbers"), EXIT_FAILURE) : EXIT_SUCCESS;
}
When run on your original input, ./a.out 12323465723
, it gives,
abcbcdfegbc
abcbcdfegw
abcwdfegbc
abcwdfegw
awbcdfegbc
awbcdfegw
awwdfegbc
awwdfegw
lcbcdfegbc
lcbcdfegw
lcwdfegbc
lcwdfegw
(I think you have made a transposition in lcwdefgw
.)