2011-08-07 94 views
0

我想先介绍look-and-say序列。它就像a = {1, 11, 21, 1211, 111221 ...python look-and-say序列改进

该系统检查前一位数字并计数数字。

1 = one 1 (so = 11)
11 = two 1 (so = 21)
21 = one 2 one 1 (so = 1211)

由于序列的规则,没有号码可以超越3,因此,创建一个翻译表可以适应,但它不是语义的,我不喜欢它。

我想要的是一个脚本,用于评估给定的值并返回一个看起来像是一样的字符串。

但是,要超越极限,我希望它甚至可以评估字符,因此它可以返回1A2b41

我一直在努力让它工作几个小时,逻辑变坏了,我现在有一个脑冻结。

这是实际上不起作用的脚本(返回错误结果),但它至少可以给你这个想法。

def seq(a): 
    k,last,result,a = 1,'','',str(a) 
    for i in range(len(a)): 
     if last==a[i]:k+=1 
     else: 
      result = result+str(k)+a[i] 
      k=1 
     last = a[i] 
    return result 
+0

这里有什么问题? –

+1

“我想要的是一个评估给定值并返回一个看起来像是一样的字符串的脚本。”要更清楚。我想要一个函数来评估look-and-say序列的下一个值,并在主文章中描述这些特征。 –

+0

就这么你知道,我总是发现它在调试我自己的代码时从长远来看更有帮助。 –

回答

4

我可以看到两个问题与您的代码:

  • resultka[i]扩大,虽然柜台k不计数字符a[i]但字符last。在这里替换a[i]last(您可能不想在第一轮添加任何东西)。

  • 在循环之后,您必须再次将计数器的最后一个值与最后一个字符一起添加(此操作尚未完成),即在循环后添加另一个result = result+str(k)+last

总体看起来

def seq(a): 
    a = str(a) 
    k,last,result = 1,a[0],'' 
    for i in range(1,len(a)): 
     if last==a[i]:k+=1 
     else: 
      result = result+str(k)+last 
      k=1 
     last = a[i] 
    result = result+str(k)+last 
    return result 
+0

我曾用'last'和'a [i]'尝试过,但主要问题是我没有在循环后设置'result'。谢谢您的帮助。但是,代码仍然返回无效结果。例如'seq('AAABBC')'返回''2A2B1C''。 –

+0

@fastreload抱歉,我的错 - 请参阅我的编辑。当然python使用从零开始的索引。 – Howard

+0

现在很好用。谢谢,所有3个答案都是正确的,但我选择你的答案,因为它与我的代码最相似。 –

14

您可以使用groupby,它只是你想要什么:

from itertools import groupby 
def lookandsay(n): 
    return ''.join(str(len(list(g))) + k for k, g in groupby(n)) 

>>> lookandsay('1') 
'11' 
>>> lookandsay('1A2b41') 
'111A121b1411' 
>>> lookandsay(lookandsay('1A2b41')) 
'311A1112111b111421' 

groupby回报连续按键和组从一个迭代的对象。密钥是为每个元素计算的函数,如果未指定,则为身份函数(如上所述)。该组是一个迭代器 - 当关键函数的值更改时会生成一个新组。所以,例如,根据文档:

# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B 
# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D 
+0

这是一个很好的方法,但并不能帮助他理解他为什么会遇到问题或他的问题。 – agf

+0

同意。霍华德已经非常广泛地报道了OP代码中的错误,除了另一种解决方案之外,我认为我没有什么需要改进的地方。 –

+0

我可以看到'groupby'允许我们做得很好,但我需要了解如何做什么,从现在开始=)。 –

4

我觉得你为什么被难倒的一部分是你使用无意义的变量名称。你很好地描述了这个问题,并用名称来称呼它,但甚至没有为你的功能使用这个名称。

如果你认为你开始的字符串是“look”,而最后一个字符串是“say”,那么这是一个开始。 result很可能不错,但是ak已经让您感到困惑。我认为,last是误导性的,因为它可能意味着先前的或最终的。

此外,Python的for实际上是foreach出于某种原因 - 您将每个字符放在一个“外观”中,因此请在循环中明确指定。

def looksay(look): 
    look = str(look) 
    prev, count, say = look[0], 1, '' 
    for char in look[1:]: 
     if char == prev: 
      count += 1 
      continue 
     say += str(count) + prev 
     prev = char 
     count = 1 
    return say + str(count) + prev 

的间隔是不那么重要,但是Python确实有standard coding style,它确实有助于可读性使用它。解析代码所花费的精神时间越少,您对该问题的关注就越多。

+0

说实话,我试图解决一个难题,因此我没有明确定义变量,而且我花了这么多时间来处理这个片段,这些变量名称并没有多大关系。在真正的编程中,我根本不这样做。代码片段完美无瑕。只是为了澄清:'continue'语句跳过下面的行并跳转到for循环中的下一步,对吗? –

+1

是的。你可以把循环的其余部分放在'else'中,但是如果你想跳过某个点以下的所有东西,我认为最好使用'continue',因为它明确表示这就是你正在做的事情。它还避免了必须对代码的另一个级别进行缩进,这个级别实际上是'for'循环的主体。我知道_feels_像变量名称,样式等并不重要,但它们确实妨碍了解代码中的算法问题。特别是当你遇到问题时,你应该花时间尽可能的清楚和明确;我会帮你的。 – agf

+0

知道了,请记住你的意见=)谢谢。 –