I'm trying to write a function to find the text from a sum of ascii numbers. All characters are uppercase , and if for example I get 155 , the function need to return AZ (65+90). Think of it like columns in an Excel table: it goes from A to Z, then AA, AB...AZ, BA, BB and etc. It needs to work for up to 4 digits. I'm trying a recursive function, but it has some errors. If I give the function 270 -> it return AAAK
, not ZZZ
, because I check if 65(A)
fits in that number
, then I go to the next if it doesn't (with the second if: number % asc + asc
). Another error is in the output of the code: 130+90
works well , AAZ
, but if I add 1 it should give me ABA
. In these cases I think I'm doing things wrong the most. Initially I wanted to use integer division ( //
) and modulo ( %
), but it didn't work.
def ascii(number):
result = ""
if number > 90:
for asc in range(65, 91):
if number % asc + asc in range(65, 91):
result += chr(asc)
result += ascii(number - asc)
break
else:
result += chr(number)
return result
if __name__ == '__main__':
result = ""
print(ascii(131))
print(ascii(130+90))
print(ascii(130+90+1))
print(ascii(130+90+39))
#output: AB, AAZ, BAZ, UTZ
Searching recursively is fine, the problem is that you don't set a limit to how deep it need to go, that is why for 270 it goes 4 levels to AAAK and not 3 to ZZZ.
So first we need to determine how deep we need to go, then the base case for the recursive function now become: in the base level return the character if the value is correct otherwise return nothing, and for the rest, for each character, we check if we get a result from the recursive case, if we do we're done otherwise we continue and if no match simple return nothing.
Something like
import itertools
A = ord("A")
Z = ord("Z")
def length(num):
if num < A:
return 0
for n in itertools.count(1):
if A*n <= num <= Z*n:
return n
elif num <= A*n:
break
return 0
def search_ascii(num, level):
if level<1:
return ""
if level==1:
if A <= num <= Z:
return chr(num)
return ""
for n in range(A,1+Z):
r = search_ascii(num-n,level-1)
if r:
return chr(n)+r
return ""
def to_ascii(num):
n = length(num)
if not n:
raise ValueError("value too small")
return search_ascii(num,n)
print(to_ascii(131))
print(to_ascii(130+90))
print(to_ascii(130+90+1))
print(to_ascii(130+90+39))
print(to_ascii(270))
print(to_ascii(155))
and the output
AB
AAZ
ABZ
OZZ
ZZZ
AZ
the non-recursive version can be done with itertools.product like so:
def to_ascii_it(num):
n = length(num)
if not n:
raise ValueError("value too small")
for chars in itertools.product(range(A,1+Z), repeat=n):
if sum(chars)==num:
return "".join(map(chr,chars))
我觉得这个设计不是很清楚,比如155既可以是65+90的组合,也可以是66+89的组合,甚至更多的其他组合。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.