How to increment string like a number?

Question:

Given the charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", how can I increment a string like following:

aabbcde -> aabbcdf -> aabbcdg -> … -> aabbcd0 -> aabbcea

I would like a snippet in Python.
Thank you!

Asked By: HiImEins

||

Answers:

you can use a for loop like this:

for character in charset:
        print("aabbc" +  character)

and then modify it so that after all combinations with "d" it prints "e" and then iterates through charset again.

Answered By: SZA

We have 62 digits:

>>> DIGITS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
>>> len(DIGITS)
62

so the easiest way to tackle the problem IMO is to implement a base-62 representation using those digits, since str->int conversion with a given set of digit characters is a well-trodden path (you can google up a quick reference implementation to base your conversion functions on if it’s one you haven’t trodden personally before):

>>> def from_b62(num: str) -> int:
...     if num.startswith("-"):
...         return -from_b62(num[1:])
...     return sum(DIGITS.index(d) * 62 ** i for i, d in enumerate(num[::-1]))
...
>>> def to_b62(num: int) -> str:
...     if num < 0:
...         return "-" + to_b62(-num)
...     d = ""
...     while num:
...         d = DIGITS[num % 62] + d
...         num //= 62
...     return d or DIGITS[0]
...

Now we can convert a string to an int in our base-62 system, add 1, and convert it back:

>>> from_b62("aabbcde") + 1
15022543
>>> to_b62(15022543)
'bbcdf'

Note that to_b62 doesn’t preserve the leading as (which are zeroes) from the original string, since they aren’t part of the numeric value, but if you put the two operations into a single function you can rjust the result to the length of the original string:

>>> def inc_b62(num: str, step=1) -> str:
...     return to_b62(from_b62(num) + step).rjust(len(num), DIGITS[0])
...
>>> inc_b62("aabbcde")
'aabbcdf'
>>> inc_b62("aabbcdf")
'aabbcdg'
>>> inc_b62("aabbcd0")
'aabbcea'
Answered By: Samwise

This returns exactly like your example:

charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"

my_string = "aabbcd0"

def incriment_str(string: str, last_char_i=None):
    if last_char_i is None:
        last_char_i = (len(string)) - 1

    last_char = string[last_char_i]
    last_char_map_i = charset.find(last_char)
    if last_char_map_i == len(charset) - 1 :
        next_char = charset[0]
        return incriment_str(my_string[:last_char_i], last_char_i - 1) + next_char
    else:
        next_char = charset[last_char_map_i + 1]   
        return my_string[:last_char_i] + next_char

# Testing
print(my_string)
for i in range(100000000000):
    my_string = incriment_str(my_string)
    print(my_string)
Answered By: David Hožič
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.