【问题标题】:replace goto using recursion使用递归替换 goto
【发布时间】:2014-06-08 07:37:45
【问题描述】:

我有一个简单的数字根计算(即,将所有数字相加为一个整数,如果总数超过一位,请重复该过程,直到得到一个数字的答案)。

我的第一个冲动是简单地计算初始字符串中数字的总和,测试结果是否超过一位,如果是,则转到求和套件的开头:

例如。

line = "123456789"
sum_digits = 0    
# label: if I could use goto, it would go to here!
n_chars = len(line)
while n_chars > 0:
    sum_digits = sum_digits + int(line[0])
    line = line[1:]
    n_chars -= 1
line = str(sum_digits)
if len(line) < 2: # all done
    print("digital root is ", sum_digits);
else:
    goto label: # need to repeat until get single digit root number

但是,当然,python 不支持“goto”——所以我想这应该写成递归函数?最好的编码方式是什么?

ps。我正在尝试使代码非常易于理解/解释,因为我正在与正在学习编程的儿子进行编码练习

【问题讨论】:

    标签: python recursion goto


    【解决方案1】:

    要替换goto,想法是在每次迭代后跟踪行的内容,然后找到它的总和。

    所以,如果我理解您的问题,以下应该有效:

    def find_root(line):
        while len(line) > 1:
             sum_digits = 0
             for num in list(line):
                 sum_digits += int(num)
             line = str(sum_digits)
        print line
    
    
    >>find_root("123456789")
    9
    >>find_root("93856")
    4
    

    【讨论】:

    • 我喜欢这个答案,因为它很容易向我儿子解释它是如何工作的。
    【解决方案2】:

    或者你也可以"do it the math way"

    def find_root(s):
        return (int(s) - 1) % 9 + 1
    

    >>> find_root("12345")
    6
    >>> find_root("8753")
    5
    >>> find_root("6743")
    2
    

    【讨论】:

    • 但是“123456789”的数字根应该是“9”而不是“0”
    • @user2147243,你是对的。这可以通过在模数之前减去 1 并在之后添加来完成。
    • 但是0 失败了。
    【解决方案3】:

    你可以试试下面的代码:

    def calc_root(num_string):
        root = 10
        num_string2 = str(num_string)
        while root >= 10:
           root = sum([int(x) for x in num_string2])
           num_string2 = str(root)
        return root
    

    这将减少到没有递归的一位数根。这个想法是,只要计算出的根等于或大于 10,它就会一直停留在 while 循环中。

    您可以在 num_string2 上添加对 isdigit 的检查并添加一个异常,但这会使代码复杂化,应该是稍后的步骤。

    【讨论】:

    • 顺便说一下,这使用了python的两个概念:1)字符串是一个字符列表2)列表理解
    【解决方案4】:

    使用递归和列表推导:

    def sumdigits(n):
        if len(n) > 1:
            t=sum([int(d) for d in n])
            return sumdigits(str(t))
        else:
            return n
    
    print sumdigits("123456789")
    
    1. 以字符串形式获取数字
    2. 如果字符串长度大于1,递归调用函数计算总和
    3. 否则返回总和

    【讨论】:

    • 非常好。现在我只需要弄清楚如何向 13 岁的孩子解释它。我可能必须将“t=sum([int(d) for d in n])”行扩展为更明显的内容,然后将其显示为最终的、更紧凑的版本。 ;)
    【解决方案5】:

    我可以建议以下几点:

    >>> def digiroot(number_string):
    ...     while len(number_string) > 1:
    ...             sum = 0
    ...             for i in number_string:
    ...                     sum += int(i)
    ...             number_string = str(sum)
    ...     print number_string
    ... 
    >>> digiroot("124")
    7
    >>> digiroot("12487")
    4
    >>> digiroot("12487123")
    1
    >>> digiroot("123456789")
    9
    

    【讨论】:

    • 我什至没有意识到尼玛的回答是正确的。我的错误,它实际上是相同的 X_x
    【解决方案6】:
    def dig_root(line):
        while len(line) > 1:
            total = 0
            for num in line:
                total += int (num)
            line = str(total)
        print "The digital root is: " + str (line)
    

    >>> dig_root("12345")

    数字根是:6

    >>> dig_root("8753")

    数字根是:5

    >>> dig_root("6743")

    数字根是:2

    我们去吧。我需要更仔细地阅读。

    【讨论】:

    • 如果总和 >10 则错过再做一次
    • 简洁的编码,但在得到超过一位数的答案时不会迭代。
    • 抱歉,我没有仔细阅读。我编辑它是正确的,除非你想使用 9 之后的剩余部分,但这不会太难改变。
    • "8753" > "23" > "5" 应该是答案。
    • 它是...对不起。
    【解决方案7】:

    尝试主循环

    编辑:抱歉,忘记重置 sum_digit

    line = "123456789"
    sum_digits = 0    
    # label: if I could use goto, it would go to here!
    
    while len(line) > 1:
       n_chars = len(line)
       while n_chars > 0:
           sum_digits = sum_digits + int(line[0])
           line = line[1:]
           n_chars -= 1
       line = str(sum_digits)
       sum_digits = 0
    
    print("digital root is ", sum_digits);
    

    【讨论】:

    • 虽然在第一个总和得出“45”之后进行迭代,但它没有得出正确的答案(“9”),因为 sum_digits 值在迭代之前没有被重置,所以你只是继续向两位数添加更多数字,然后满足退出条件(即无限循环)?
    • 这会导致无限循环。它设置 line 等于 string cast sum 然后重复循环,因为line 总是大于长度 1。
    • 对不起,inf 循环,第一次没有真正运行代码:3
    猜你喜欢
    • 2021-04-02
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    相关资源
    最近更新 更多