Как увеличить буквенные символы, не получая специальных символов после z? - PullRequest
0 голосов
/ 02 февраля 2019

Мне нужно создать программу, которая получает строку и целое число n ;он будет увеличивать каждый символ строки на n символов;например, если строка имеет значение «abc» и n = 1 , вывод будет «bcd», если n = 2 , это будет «cde».

Пока что я написал этот код

string = list( input( "Insert a string, it will be codified: " ) )

n = int( input( "Insert an integer, each string's character will be increased by that number: " ) )

for characterIndex in range( len( string ) ):

    string[characterIndex] = chr( ord( string[characterIndex] ) + n )

print( ''.join( string ) )

Тем не менее, если я введу "xyz" и n = 1 , я получу "yz {", что делаетсмысл, поскольку следующий символ ascii в "z" это "{".Вы можете себе представить, что для более высоких n становится хуже;Я пытался решить эту проблему для любого n по модулю, пытался извлечь выгоду из того факта, что есть 26 букв, но я все еще не могу найти математическое приращение, которое обнаруживает, когда строка имеетбыл увеличен дальше, чем "z", поэтому он "возвращается" к "a".

Есть какие-нибудь рекомендации?Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 02 февраля 2019

Это обман, но я бы выбрал следующий подход:

def string_bump(s):
    letter_list = "abcdefghijklmnopqrstuvwxyza" #note the extra 'a' at the end
    old_positions = []; new_positions = []
    for character in s:
        old_positions.append(letter_list.find(character))
    for pos in old_positions:
        new_positions.append(pos+1)
    new_string = ""
    for pos in new_positions:
        new_string += letter_list[pos]
    return new_string

for s in ["abc", "bcd", "xyz"]:
    print("before:", s, "after:", string_bump(s))

печатает:

before: abc after: bcd
before: bcd after: cde
before: xyz after: yza

По сути, я сканирую строку, чтобы преобразовать символы в позиции валфавитная строка;добавьте 1 к каждой позиции;и восстановить строку из этих позиций.«Чит» добавляет дополнительный «а», поэтому позиция-25 (считая от 0) «z» переводит в эту дополнительную позицию-26 «а».

Если это вас оскорбляет, вы можете оставитьлишний «а» и вместо этого просто сделайте еще один проход в списке позиций, и когда вы увидите «26» (что будет после конца letter_list без «а»), сбейте его до нуля.

Это просто подтверждение концепции для вашего примера;чтобы поддержать произвольное смещение, вы должны расширить letter_list для полного алфавита и использовать по модулю на входе (например, n = n%26), чтобы вход остался в диапазоне.

Кроме того, я бы фактически использовал выражения списка вместо циклов for, но вы, возможно, еще не встречали их, поэтому вместо них я использовал более явные циклы for.

0 голосов
/ 02 февраля 2019

Вот модифицированный ответ из комментариев:

c = chr((ord(a) - 97) % 25 + 97)
0 голосов
/ 02 февраля 2019

Давайте разберем его так, чтобы отдельные шаги с именованными переменными прояснили, с чем вы имеете дело:

asciiValue = ord(string[characterIndex])
alphabetIndex = asciiValue - ord('a')
alphabetIndex = (alphabetIndex + n) % 26
asciiValue = alphabetIndex + ord('a')
string[characterIndex] = chr(asciiValue)

Обратите внимание, что в приведенном выше примере предполагается, что ваша входная строка состоит только из строчных букв ASCII.Для символов в верхнем регистре вам нужно вычесть (и заново добавить) ord('A').

Интеграция в существующий код:

def shift_letter(letter, n):
    asciiValue = ord(letter)
    alphabetIndex = asciiValue - ord('a')
    alphabetIndex = (alphabetIndex + n) % 26
    asciiValue = alphabetIndex + ord('a')
    return chr(asciiValue)

string = list( input( "Insert a string, it will be codified: " ) )

n = int( input( "Insert an integer, each string's character will be increased by that number: " ) )

for characterIndex in range( len( string ) ):
    string[characterIndex] = shift_letter(string[characterIndex], n)

print( ''.join( string ) )
...