python 的“look-and-say”序列得到改进

发布于 2024-11-28 08:01:46 字数 668 浏览 3 评论 0原文

我想首先介绍一下“看-说”序列。它就像a = {1, 11, 21, 1211, 111221 ...

系统检查前一个数字并计算数字。

1 = 一 1(所以 = 11)
11 = 两个 1(所以 = 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

I would like to introduce look-and-say sequence at first. It goes like a = {1, 11, 21, 1211, 111221 ...

The system is it checks the previous digit and counts the numbers.

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

As a rule of the sequence, no number can go beyond 3, so creating a translation table can fit in. But it is not semantic, I don't like it.

What I want is, a script which evaluates the given value and return a look-and-say-alike string.

However, to go beyond out limits, I want it to even evaluate chars, so it can return 1A2b41.

I have been trying to make it work for hours, the logic went bad and I am having a brainfreeze at the moment.

Here is the script that actually doesn't work(returns false results), but it can give you the idea, at least.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一向肩并 2024-12-05 08:01:46

您可以使用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

You can use groupby, it's just what you want:

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 returns consecutive keys and groups from an iterable object. The key is a function computed for each element, or an identity function if not specified (as above). The group is an iterator - a new group is generated when the value of the key function changes. So, for instance, according to the documentation:

# [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
万劫不复 2024-12-05 08:01:46

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

  • 结果ka[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

I can see two issues with your code:

  • The result is expanded by k and a[i] although the counter k does not count chars a[i] but chars last. Replace a[i] by last here (you may not want to add anything in the first round).

  • After the loop you have to add the last value of the counter together with the last character again (this was not yet done), i.e. add another result = result+str(k)+last after the loop.

In total it looks like

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
一场信仰旅途 2024-12-05 08:01:46

我认为你被难住的部分原因是你使用了无意义的变量名。您很好地描述了问题并按名称调用了它,但甚至没有在您的函数中使用该名称。

如果您将开头的字符串视为“look”,将结尾的字符串视为“say”,那么这就是一个开始。 结果可能很好,但ak让你感到困惑。我认为 last 具有误导性,因为它可以表示先前的或最终的。

另外,Python 的 for 实际上是 foreach ,这是有原因的——您一次获取“look”中的每个字符,因此在循环中明确执行。

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 确实有一个标准编码风格,并且它确实有助于使用它的可读性。您花在解析代码上的精神时间越少,您对问题的关注就越多。

I think part of why you got stumped is your use of meaningless variable names. You described the problem quite well and called it by name, but didn't even use that name for your function.

If you think of the string you start with as "look", and the one you end up with as "say", that is a start. result is probably fine but a and k have confused you. last is, I think, misleading, because it can mean either previous or final.

Also, Python's for is really foreach for a reason -- you're taking each character in the "look" one at a time, so do it explicitly in the loop.

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

The spacing is less important, but Python does have a standard coding style, and it does help readability to use it. The less mental time you have to spend parsing your code, the more focus you have for the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文