I need a simple program that given a string, returns to me the next one in the alphanumeric ordering (or just the alphabetic ordering).
f(\"aaa\")=\"aab\"
f(
Sucks that python doesn't have what ruby has: String#next
So here's a shitty solution to deal with alpha-numerical strings:
def next_string(s):
a1 = range(65, 91) # capital letters
a2 = range(97, 123) # letters
a3 = range(48, 58) # numbers
char = ord(s[-1])
for a in [a1, a2, a3]:
if char in a:
if char + 1 in a:
return s[:-1] + chr(char + 1)
else:
ns = next_string(s[:-1]) if s[:-1] else chr(a[0])
return ns + chr(a[0])
print next_string('abc') # abd
print next_string('123') # 124
print next_string('ABC') # ABD
# all together now
print next_string('a0') # a1
print next_string('1a') # 1b
print next_string('9A') # 9B
# with carry-over
print next_string('9') # 00
print next_string('z') # aa
print next_string('Z') # AA
# cascading carry-over
print next_string('a9') # b0
print next_string('0z') # 1a
print next_string('Z9') # AA0
print next_string('199') # 200
print next_string('azz') # baa
print next_string('Zz9') # AAa0
print next_string('$a') # $b
print next_string('$_') # None... fix it yourself
Not great. Kinda works for me.
I don't think there's a built-in function to do this. The following should work:
def next_string(s):
strip_zs = s.rstrip('z')
if strip_zs:
return strip_zs[:-1] + chr(ord(strip_zs[-1]) + 1) + 'a' * (len(s) - len(strip_zs))
else:
return 'a' * (len(s) + 1)
Explanation: you find the last character which is not a z
, increment it, and replace all of the characters after it with a
's. If the entire string is z
's, then return a string of all a
's that is one longer.
Are the answers at How would you translate this from Perl to Python? sufficient? Not 100% what you're asking, but close...
A different, longer, but perhaps more readable and flexible solution:
def toval(s):
"""Converts an 'azz' string into a number"""
v = 0
for c in s.lower():
v = v * 26 + ord(c) - ord('a')
return v
def tostr(v, minlen=0):
"""Converts a number into 'azz' string"""
s = ''
while v or len(s) < minlen:
s = chr(ord('a') + v % 26) + s
v /= 26
return s
def next(s, minlen=0):
return tostr(toval(s) + 1, minlen)
s = ""
for i in range(100):
s = next(s, 5)
print s
You convert the string into a number where each letter represents a digit in base 26, increase the number by one and convert the number back into the string. This way you can do arbitrary math on values represented as strings of letters.
The ''minlen'' parameter controls how many digits the result will have (since 0 == a == aaaaa).