【问题标题】:Shifting all the alphabets of a string by a certain step将字符串的所有字母移动某个步骤
【发布时间】:2020-07-24 00:11:27
【问题描述】:
  • 输入:['baNaNa', 7]#字符串和步长
  • required output : 'utGtGt' # 字符串的每个字符向后移动一个步长
import ast  
in_string = input()  
lis = ast.literal_eval(in_string)  
st = lis[0]  
step = lis[1]  
alphabets = 'abcdefghijklmnopqrstuvwxyz'  
password = ''  
for letter in st:  
    if letter in alphabets:  
        index_val = alphabets.index(letter) - (step)  
        password += alphabets[index_val]  

print(password)

我得到的输出是'utgtgt'。我想要'utGtGt'。对此的帮助将不胜感激。

【问题讨论】:

  • 当我尝试时我有'uttt'
  • 'A' 应该变成什么?或者abcdef中的任何一个?
  • 因为 baNaNa 应该返回 utGtGt 我猜a 会变成t
  • 这能回答你的问题吗? Caesar Cipher Function in Python

标签: python python-3.x string loops indexing


【解决方案1】:

字符串模块有 create a transformation dictionarytranslate method 的方法来做你想做的事:

st = "baNaNa"
step = 7
alphabets = 'abcdefghijklmnopqrstuvwxyz'
alph2 = alphabets.upper() 

# lower case translation table
t = str.maketrans(alphabets, alphabets[-step:]+alphabets[:-step])

# upper case translation table
t2 = str.maketrans(alph2, alph2[-step:]+alph2[:-step])

# merge both translation tables
t.update(t2)

print(st.translate(t)) 

输出:

utGtGt

你给它原始字符串和一个相等的长字符串来映射字母并使用str.translate(dictionary) 应用那个字典。

分割后的字符串等于:

print(alphabets)
print(alphabets[-step:]+alphabets[:-step])

abcdefghijklmnopqrstuvwxyz
tuvwxyzabcdefghijklmnopqrs

这就是你的step 的用途。


如果您从未见过使用字符串切片,请参阅 Understanding slice notation

【讨论】:

  • 真的很整洁!给出的答案似乎只移动小写字符。一个人将如何转移大写字符呢? (例如 baNaNautGtGt,而不是 utNtNt
  • @saha 我认为这很清楚 - 你对大写字母应用相同的东西。我也编辑了它们。
【解决方案2】:

通过处理每个字符并检查它的基数并进行相应的计算来帮助您得出结果

def func(string, size):
    if size%26==0:
        size=26
    else:
        size=size%26
    new_str = ''    
    for char in string:
        if char.isupper():
            if ord(char)-size<ord('A'):
                new_str+=chr(ord(char)-size+26)
            else:
                new_str+=chr(ord(char)-size)
        elif char.islower():
            if ord(char)-size<ord('a'):
                new_str+=chr(ord(char)-size+26)
            else:
                new_str+=chr(ord(char)-size)         
    return new_str


res =func('baNaNa', 7)   
print(res)

# output utGtGt

【讨论】:

    【解决方案3】:

    这是一个简单的解决方案,它使用% 模运算符来向后移动字母。

    它基本上收集了反向索引查找字典中的所有字母,因此查找字母位置是O(1),而不是使用list.index(),这是线性O(N) 查找。

    然后它遍历每个字母并根据字母索引计算移位值,例如对于移位值为7的字母a,计算将是(0 - 7) % 26,这将给出19u的位置。

    然后,一旦你有了这个移位值,根据原始字母的大小写将其转换为大写或小写。

    最后我们只是将str.join() 的结果列表合并为一个字符串。这比使用+= 连接字符串更有效。

    演示:

    from string import ascii_lowercase
    
    def letter_backwards_shift(word, shift):
        letter_lookups = {letter: idx for idx, letter in enumerate(ascii_lowercase)}
        alphabet = list(letter_lookups)
    
        result = []
        for letter in word:
            idx = letter_lookups[letter.lower()]
            shifted_letter = alphabet[(idx - shift) % len(alphabet)]
    
            if letter.isupper():
                result.append(shifted_letter.upper())
            else:
                result.append(shifted_letter.lower())
    
        return ''.join(result)
    

    输出:

    >>> letter_backwards_shift('baNaNa', 7)
    utGtGt
    

    我可能会选择@Patrick Artner's pythonic 解决方案。我只是将上述实现展示为一个学习练习:-)。

    【讨论】:

      猜你喜欢
      • 2019-09-28
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 2019-09-29
      • 1970-01-01
      • 2011-09-20
      • 2016-01-01
      • 1970-01-01
      相关资源
      最近更新 更多