Reputation: 477
Given a sequence of characters, return next following in alphabetical order.
Example: given 'A' it should return 'B', 'Z' -> 'AA', 'ZYZ' -> 'ZZA'
etc.
One relevant reference using modulo and math i have found is in c#. Instead of converting it into python, i came up with my own solution.
What would be a more effective algorithmic approach than the one below?
import string
def increment_excel(s=''):
"""
A->B, Z->AA, AZ->BA, KZZ->LAA
"""
def wrapped(s):
if not s:
return string.uppercase[0]
ind = string.uppercase.index(s[-1])
if ind < len(string.uppercase) - 1:
return s[:-1] + string.uppercase[ind + 1]
return wrapped(s[:-1]) + string.uppercase[0]
return wrapped(s.upper().replace(' ',''))
increment_excel('TRYME') # -> 'TRYMF'
increment_excel('TRY ZZ') # -> 'TRZAA'
increment_excel('ABCC') # -> 'ABCD'
increment_excel('ZZ Z') # -> 'AAAA'
Upvotes: 1
Views: 266
Reputation: 1034
Please check my solution, I tested from my side and it worked.
def seqconverter(a):
def converter(number):
retval = str()
while number:
x = (number - 1) % 26
number = (number - 1) / 26
retval = '%s%s' % (chr(x + 65), retval)
return retval
def numconverter(a):
res = 0
for c in a:
res *= 26
res += ord(c) - 64
return res
return converter(numconverter(a) + 1)
if __name__=='__main__':
print(seqconverter('ZYZ'))
print(seqconverter('ZZA'))
print(seqconverter('XY'))
Output:
ZZA
ZZB
XZ
------------------
(program exited with code: 0)
Press return to continue
Upvotes: 1
Reputation: 241691
Here's a solution which just uses string manipulation.
Leaving aside the normalization of the string (uppercase it, strip blanks), the function essentially finds the suffix consisting of an optional letter other than Z followed by any number of Zs (including none). The trailing Zs are all changed to A, while the last character before the Zs (if any) is incremented. Finally, an A is prepended if the string consists only of Zs.
import re
import string
succ_tb = string.maketrans(string.uppercase,
string.uppercase[1:]+string.uppercase[0])
up_tb = string.maketrans(string.lowercase, string.uppercase)
suff_re = re.compile('(([A-Y]?)Z*)$')
def increment_excel(s):
return suff_re.sub(
lambda m: (('' if m.group(2) else 'A') +
m.group(1).translate(succ_tb)),
s.translate(up_tb, ' '))
Upvotes: 1
Reputation: 46669
Try:
def increment_excel(s=''):
arr = list(s.upper().replace(' ', ''))
if arr:
arr.reverse()
n = 1
for i in range(len(arr)):
if ord(arr[i])+n <= ord('Z'):
arr[i] = chr(ord(arr[i]) + n)
n = 0
else:
arr[i] = 'A'
n = 1
if n == 1:
arr.append('A')
arr.reverse()
return ''.join(arr)
Upvotes: 1