【问题标题】:Crazy Challenge: Rotating Letters in Python Encipher Function [closed]疯狂挑战:在 Python 加密函数中旋转字母 [关闭]
【发布时间】:2014-11-27 21:13:29
【问题描述】:

我正在尝试编写一个函数rot(c,n),它将单个字符 c 在字母表中向前旋转 n 个位置。

def rot(c,n):
""" rotate c forward by n characters,
    wrapping as needed; only letters change
"""

if 'a' <= c <= 'z':          # lower-case
    new_ord = ord(c) + n
    if new_ord > ord('z'):
        new_ord = new_ord - (2*n)
elif 'A' <= c <= 'Z':        # upper-case
    new_ord = ord(c) + n 
    if new_ord > ord('Z'):
        new_ord = new_ord - (2*n)

else:                        # non-alpha
    new_ord = ord(c)
return chr(new_ord)

但是我想要的输出如下:

>>> rot('a', 2)
'c'
>>> rot('y', 2)
'a'
>>> rot('A', 3)
'D'
>>> rot('Y', 3)
'B'
>>> rot('!', 4)
'!'

我不断得到错误的输出。谁能告诉我我做错了什么?

【问题讨论】:

  • 提示:new_ord = new_ord - (2*n).
  • 你到底是什么意思。
  • 他的意思是,那行错了。
  • 来吧,试着解决它:假设 ord('a') 是 97,ord('z') 是 122,假设 n 是 2,那么 ord('z') + 2 - 2 * 2 给你?考虑到预期的输出是 ord('b'),实际需要什么计算?如果你想学习,你必须通过铁环。
  • rot('y', 2) 为例。最初,new_ord 是比z 多一个字母的任何字符。 if new_ord &gt; ord('z'): 行检测到这一点,并说“从值中减去 2*n”。所以这封信将四个字符回拨到 w。

标签: python add letters


【解决方案1】:

你的问题在这里:

new_ord = new_ord - (2*n)

这个想法是,当您超过 z 时,您必须完全删除整个字母表,而不是删除刚刚添加的两倍。

试试:

new_ord = new_ord - 26

【讨论】:

  • 如果我这样做rot('a', 100)怎么办?
  • 谢谢。你很有帮助
  • 好电话,@Kevin - 在我的回答中也解决了这个问题
【解决方案2】:

两个班轮:(不要在家里尝试这个)

def rot(c, n):
    start = 97 if c.islower() else 65 if c.isupper() else False      
    return chr((ord(c)-start+n)%26 + start) if start else c

【讨论】:

    【解决方案3】:

    此版本还支持“负旋转”;我还把条件句换成了.isupper().islower(),因为我发现它们的可读性稍微好一些(并且不太容易出现一个错误):

    def rot(c,n):
        """ rotate c forward by n characters,
            wrapping as needed; only letters change
        """
        new_ord = ord(c) + (n % 26)
        if c.isupper():
            if new_ord > ord('Z'):
                new_ord -= 26
            elif new_ord < ord('A'):
                new_ord += 26
            return chr(new_ord)
        elif c.islower():
            if new_ord > ord('z'):
                new_ord -= 26
            elif new_ord < ord('a'):
                new_ord += 26
            return chr(new_ord)
        return c
    

    【讨论】:

      【解决方案4】:

      或者:

      import string
      from itertools import cycle
      
      def make_rotation_tables(n):    
          uc, lc = map(cycle, (string.uppercase, string.lowercase))
          nchar = len(string.uppercase)
          part = slice(n, n + nchar)
          rotate = lambda n, it: ''.join(
              [next(it) for i in xrange(26+nchar)][part])
          rot_letters = ''.join(map(lambda x: rotate(n, x), [uc, lc]))    
          return string.maketrans(string.letters, rot_letters)
      
      rottbl = make_rotation_tables(1)
      print 'Caesar dixit: "Veni, vidi, vici!"'.translate(rottbl)
      >>> Dbftbs ejyju: "Wfoj, wjej, wjdj!"
      

      【讨论】:

        猜你喜欢
        • 2011-12-22
        • 1970-01-01
        • 2017-01-25
        • 1970-01-01
        • 2023-02-25
        • 2011-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多