كيف يمكنني الحصول على السلسلة التالية، في ترتيب أبجدي رقمي، في بيثون؟
سؤال
أحتاج إلى برنامج بسيط يعطى سلسلة، وإرجاع لي واحد التالي في الطلب الأبجدي الرقمي (أو مجرد الطلب الأبجدي).
f("aaa")="aab"
f("aaZ")="aba"
وما إلى ذلك وهلم جرا.
هل هناك وظيفة لهذا في واحدة من الوحدات بالفعل؟
المحلول
لا أعتقد أن هناك وظيفة مدمجة للقيام بذلك. يجب أن تعمل ما يلي:
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: تجد الشخصية الأخيرة التي ليست z
, ، زيادة ذلك، واستبدال كل الشخصيات بعد ذلك a
'س. إذا كانت السلسلة بأكملها z
، ثم إرجاع سلسلة من الكل a
هذا هو واحد لفترة أطول.
نصائح أخرى
هي الإجابات في كيف ترجم هذا من بيرل إلى بيثون؟ كاف؟ ليس 100٪ ما تسأل، ولكن إغلاق ...
حل مختلف، ولكن ربما أكثر قابلية للقراءة ومرنة:
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
قمت بتحويل السلسلة إلى رقم حيث يمثل كل حرف رقما في قاعدة 26، وزيادة الرقم بأحد واحدا وتحويل الرقم مرة أخرى إلى السلسلة. وبهذه الطريقة يمكنك القيام به الرياضيات التعسفية على القيم الممثلة كسلاسل من الحروف.
يتحكم المعلمة في "Minlen" عدد الأرقام التي ستكون لها النتيجة (منذ 0 == A == AAAAA).
تمتص أن بيثون ليس لديه ما لديه روبي: String#next
إذن إليك حل غزر للتعامل مع سلاسل ألفا العددية:
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
ليس عظيما. كيندا يعمل بالنسبة لي.