Interconvert strings and integers
1. Problem statement
Convert a string representation of an integer into the integer and vice versa (Aziz et al., 2018, p. 75).
2. Insights
For the simplest case, there is only a single digit and doing the conversion is just a numerical lookup (using ASCII values directly)
3. Solutions
3.1. int
to str
If the number is negative, we have to keep track of this separately. It simplifies our algorithm if we always only work with positive integers, so we also make the number positive if necessary as a preparatory step.
Now we have to repeatedly divide the number and get the modulo as well. This way we only ever concern ourselves with one digit at a time.
One thing to keep in mind is that the string result will never be empty, because
an integer type's "constructor" is some numeric value. So we use a while True
loop conditional here because we know that we must do some amount of building up
the result string.
Another thing to keep in mind is that we build up a list in reverse because it technically requires less copying (we avoid moving array elements by appending to it).
Note that we had to use the ord()
and chr()
built-ins. These make working
with ASCII codepoints easier.
3.1.1. Complexity
- Time: \(O(d)\) where \(d\) is the number of digits in the input number.
- Space: \(O(d)\) (same as above).
3.2. str
to int
If the input is the empty string, we return a default value, zero.
Now we have to consider if the number is negative, as before.
We now loop through the input string in reverse. We start with the rightmost digit and work our way left.
3.2.1. Complexity
- Time: \(O(d)\) where \(d\) is the number of digits in the input number.
- Space: \(O(1)\) because we only need to use a single integer variable for additional space (beyond the input string, whose memory allocation is not part of our algorithm's behavior).
3.2.2. Variation with functools
This version uses functools.reduce()
from the functools
module to iterate in
through the input string in the opposite direction (left-to-right). The trick is
to multiply whatever previous (partial) sum we have by 10 on each subsequent
iteration.
Note the s[s[0] == "-":]
trick — this simplifies to s[1:]
(skipping the
first character) only if the first character is a negative sign symbol.
One other difference is that we no longer have to raise anything to a power
using the **
operator, because we spread this out over each iteration by
multiplying the partial sum by 10.