6

私が実装しようとしているのは、文字列を 1 文字ずつインクリメントする関数です。たとえば、次のようになります。

'AAA' + 1 = 'AAB'
'AAZ' + 1 = 'ABA'
'ZZZ' + 1 = 'AAAA'

最初の 2 つのケースの関数を実装しましたが、3 番目のケースの解決策が思いつきません。

これが私のコードです:

def new_sku(s):
    s = s[::-1]
    already_added = False
    new_sku = str()

    for i in s:
        if not already_added:
            if (i < 'Z'):
                already_added = True
            new_sku += chr((ord(i)+1)%65%26 + 65)
        else:
            new_sku += i

    return new_sku[::-1]

助言がありますか ?

4

10 に答える 10

9

全単射の numerationを扱っている場合は、とにかく全単射表現との間で変換する関数がある (または持つべき) でしょう。整数に変換し、インクリメントしてから元に戻すだけで、はるかに簡単になります。

def from_bijective(s, digits=string.ascii_uppercase):
    return sum(len(digits) ** i * (digits.index(c) + 1)
               for i, c in enumerate(reversed(s)))

def to_bijective(n, digits=string.ascii_uppercase):
    result = []
    while n > 0:
        n, mod = divmod(n - 1, len(digits))
        result += digits[mod]
    return ''.join(reversed(result))

def new_sku(s):
    return to_bijective(from_bijective(s) + 1)
于 2013-07-31T09:10:24.933 に答える
3

どうですか?

def new_sku(s):
    s = s[::-1]
    already_added = False
    new_sku = str()

    for i in s:
        if not already_added:
            if (i < 'Z'):
                already_added = True
            new_sku += chr((ord(i)+1)%65%26 + 65)
        else:
            new_sku += i

    if not already_added: # carry still left?
        new_sku += 'A'

    return new_sku[::-1]

サンプルラン:-

$ python sku.py Z
AA
$ python sku.py ZZZ
AAAA
$ python sku.py AAA
AAB
$ python sku.py AAZ
ABA
于 2013-07-31T09:03:12.030 に答える
3

「AAA」、「ZZZ」、... は、操作する値の表現と考える必要があります。

まず、値を解析します。

val = sum(pow(26, i) * (ord(v) - ord('A') + 1) for i, v in enumerate(value[::-1]))

次に、それに値を追加します。

val = val + 1

編集

最終的な値は次のように与えられます。

res = ""
while val > 0:
     val, n = divmod(val - 1, 26)
     res = chr(n+ord('A')) + res

ゼロの表現がないため、divmod に渡される値を各ターンでデクリメントする必要があります。これは、リスト内包表記で行う方法が見つかりませんでした。

編集

ord()andではなく、andchr()を使用することができます。string.ascii_uppercase.index()string.ascii_uppercase[]

于 2013-07-31T09:17:48.163 に答える
2

ここでいくつかの再帰を利用できます:

def new_sku(s):
    s = s[::-1]
    new_s = ''
    return expand(s.upper(), new_s)[::-1]

import string
chars = string.ascii_uppercase

def expand(s, new_s, carry_forward=True):

    if not s:
        new_s += 'A' if carry_forward else ''
        return new_s

    new_s += chars[(ord(s[0]) - ord('A') + carry_forward) % 26]

    # Slice the first character, and expand rest of the string
    if s[0] == 'Z': 
        return expand(s[1:], new_s, carry_forward)
    else:
        return expand(s[1:], new_s, False)


print new_sku('AAB')
print new_sku('AAZ')
print new_sku('ZZZ')
print new_sku('aab')
print new_sku('aaz')
print new_sku('zzz')

出力:

AAC
ABA
AAAA
AAC
ABA
AAAA
于 2013-07-31T09:28:29.450 に答える
1
alp='ABCDEFGHIJKLMNOPQRSTUVWXYZA'
def rec(s):
    if len(s)==0:return 'A'
    last_letter=s[-1]
    if last_letter=='Z':return rec(s[:-1])+'A'
    return s[:-1]+alp[(alp.find(last_letter)+1)]

結果

>>> rec('AAA')
'AAB'
>>> rec('AAZ')
'ABA'
>>> rec('ZZZ')
'AAAA'
>>> rec('AZA')
'AZB'
于 2013-07-31T09:12:21.190 に答える
1

これを、キャリーを使用した base-26 の追加のように実装します。

したがって、文字列の右側から始めて、1 を追加します。Z に達したら、A にラップし、左端の次の文字を 1 つ上げます。一番左の文字が Z に達したら、文字列の左側に A を追加します。

s = ["Z","Z","Z"]
done = 0

index = len(s) - 1
while done == 0:
    if s[index] < "Z":
        s[index] = chr(ord(s[index]) + 1)
        done = 1
    else:
        s[index] = "A"
        if index == 0:
            s = ["A"] + s
            done = 1
        else:
            index = index - 1

print s
于 2013-07-31T09:04:51.183 に答える
1

文字列がすべて s であるかどうかを確認し、そうである場合は、 sだけで構成されるZlength の文字列に置き換えます。len(s) + 1A

if s == "Z" * len(s):
    return "A" * (len(s) + 1)
于 2013-07-31T09:05:08.933 に答える
0

for-elseループを使用できます:

from string import ascii_uppercase as au

def solve(strs):
    lis = []
    for i, c in enumerate(strs[::-1], 1):
        ind = au.index(c) + 2
        lis.append(au[(ind%26)-1])
        if ind <= 26:
            break
    else:
        # This will execute only if the for-loop didn't break.
        lis.append('A')

    return strs[:-1*i] + "".join(lis[::-1])

print solve('AAA')
print solve('AAZ')
print solve('ZZZ')
print solve('AZZZ')
print solve('ZYZZ')
print solve('ZYYZZ')

出力:

AAB
ABA
AAAA
BAAA
ZZAA
ZYZAA
于 2013-07-31T09:17:59.463 に答える