Your current approximation to the problem is correct. Although, you need to be really careful that you are handling all the cases which it is not clear and this will make my answer a bit longer than needed.
A correct way to see this problem is from a Dynamic Programming perspective. Let's consider your input string as message
and its length as n
.
To decode a message
of n
characters, you need to know in how many ways you can decode message
using n - 1
characters and a message
using n - 2
characters. That is,
A message of n
characters.
1
1 2 3 4 5 6 7 8 9 0 1
+---+---+---+---+---+---+---+---+---+---+---+
message | 1 | 2 | 3 | 4 | 1 | 2 | 3 | 1 | 4 | 1 | 2 |
+---+---+---+---+---+---+---+---+---+---+---+
Using a 1 digit and a message
of n - 1
characters long.
1
1 2 3 4 5 6 7 8 9 0 1
+---+---+---+---+---+---+---+---+---+---+ +---+
message | 1 | 2 | 3 | 4 | 1 | 2 | 3 | 1 | 4 | 1 | + | 2 |
+---+---+---+---+---+---+---+---+---+---+ +---+
Using a 2 digits and a message
of n - 2
characters long.
1
1 2 3 4 5 6 7 8 9 0 1
+---+---+---+---+---+---+---+---+---+ +---+---+
message | 1 | 2 | 3 | 4 | 1 | 2 | 3 | 1 | 4 | + | 1 | 2 |
+---+---+---+---+---+---+---+---+---+ +---+---+
Now, you may ask yourself:
How do I calculate in how many ways you can decode message
of n - 1
characters and of n - 2
characters?
It's actually in the same way. Eventually you will reduce it to its base case.
Let's say ways[n]
its the number of ways you can decode message
of n
characters. Then, you can put ways[n]
in this way,
ways[n] = ways[n - 1] + ways[n - 2]
(Since there is no clue how you'd define the number of ways for an empty string I considered it as 1
.)
With proper constraints and base case,
n = 0
,
ways[n] = 1
n > 1
and message[n]
is valid and message[n - 1:n]
is valid,
ways[n] = ways[n - 1] + ways[n - 2]
n > 1
and message[n]
is valid and message[n - 1:n]
is not valid,
ways[n] = ways[n - 1]
n > 1
and message[n]
is not valid and message[n - 1:n]
is valid,
ways[n] = ways[n - 2]
otherwise,
ways[n] = 0
An iterative decode
function in C may look as follows,
int decode(char* message, size_t len) {
int i, w, ways[] = { 1, 0 };
for(i = 0, w; i < len; ++i) {
w = 0;
if((i > 0) && ((message[i - 1] == '1') || (message[i - 1] == '2' && message[i] < '7'))) {
w += ways[1];
}
if(message[i] > '0') {
w += ways[0];
}
ways[1] = ways[0];
ways[0] = w;
}
return ways[0];
}
You can see it here at ideone. I'm using constant extra memory for the calculation.