简体   繁体   English

如何计算 integer 中递归总和为给定数字的数字对

[英]How can I count the pairs of digits within an integer that sum to a given number recursively

Here's what I need to do:这是我需要做的:

Write 1 function that passes 1 parameter(the given number)写入 1 个 function 传递 1 个参数(给定数量)

Use recursion only仅使用递归

return the number of pairs of digits that sum to 10返回总和为 10 的数字对的数量

For example, if the parameter is 734655, then it should return 3 as 7+3, 4+6 and 5+5 are 3 pairs that sum to 10例如,如果参数是 734655,那么它应该返回 3,因为 7+3、4+6 和 5+5 是 3 对,总和为 10

What I have come out with is:我得出的是:

begin with the 1st digit, check the rest all digits, then goto 2nd digit, check 3rd....to the last digit.从第 1 位开始,检查 rest 所有数字,然后转到第 2 位,检查第 3 位......到最后一位。 The base case is when the current_index reaches the last digit/基本情况是 current_index 达到最后一位/

It would be so easy to solve with loops, whereas I am asked to use recursion, I'm really confused about what should I do in each call, or if there would be a recursion within another recursion...用循环解决它会很容易,而我被要求使用递归,我真的很困惑我应该在每次调用中做什么,或者在另一个递归中是否会有递归......

One way to solve this recursively operates on the count of digits.解决这个问题的一种方法是递归地对位数进行操作。 For a digit x that's present (has positive count), check if there is also some y such that x + y equals the specified total (eg, 10 ).对于存在的数字x (具有正数),检查是否还有一些y使得x + y等于指定的总数(例如, 10 )。 If y is present (has positive count), return 1 plus the recursively calculated number of pairs in the remaining digits without x and y .如果y存在(具有正数),则返回1加上剩余数字中递归计算的对数,没有xy If not, return the recursively calculated number of pairs in the remaining digits without x .如果不是,则返回递归计算的剩余数字中不带x的对数。 The base case returns 0 when there are no digits remaining.当没有剩余数字时,基本情况返回0

Here's an example implementation in Python.这是 Python 中的示例实现。 pair_present is a boolean, but gets converted to an integer when used in a sum ( 1 for True , and 0 for False ). pair_present是一个 boolean,但在 sum 中使用时会转换为 integer( 1表示True0表示False )。 num_pairs was written as a pure function, such that its arguments are not destructively modified. num_pairs被编写为纯 function,因此其 arguments 不会被破坏性修改。

from collections import Counter

def num_pairs(digits, total=10):
    try:
        x = next(digits.elements())
    except StopIteration:
        # base case: no digits
        return 0
    digits = digits - Counter({x: 1})
    y = total - x
    pair_present = digits[y] > 0
    digits = digits - Counter({y: 1})
    return pair_present + num_pairs(digits, total=total)

number = 734655
digits = Counter(int(c) for c in str(number))
print(num_pairs(digits))  # 3

A similar approach could operate directly on the string representation of the number, instead of the count of digits.类似的方法可以直接对数字的字符串表示进行操作,而不是对数字计数。 For the first digit x in the number, check if there is also some y such that x + y equals the specified total (eg, 10 ).对于数字中的第一个数字x ,检查是否还有一些y使得x + y等于指定的总数(例如10 )。 If y is present, return 1 plus the recursively calculated number of pairs in the remaining string without x and y .如果y存在,则返回1加上剩余字符串中没有xy的递归计算的对数。 If not, return the recursively calculated number of pairs in the remaining string without x .如果不是,则返回剩余字符串中递归计算的不带x的对数。 The base case returns 0 when there are no digits remaining.当没有剩余数字时,基本情况返回0

Here's an example implementation in Python.这是 Python 中的示例实现。

def num_pairs(string, total=10):
    if len(string) == 0:
        return 0
    x = int(string[0])
    string = string[1:]  # remove x from string
    y = total - x
    pair_present = str(y) in string
    if pair_present:
        string = string.replace(str(y), '')  # remove y from string
    return pair_present + num_pairs(string, total=total)

number = 734655
print(num_pairs(str(number)))  # 3

Compared to the approaches above, the following iterative approach has the benefits that 1) it takes the number itself as input, 2) avoids the object copying in the earlier solutions (used earlier to avoid destructive modification of the input), and 3) is seemingly a more straightforward way to solve the problem.与上述方法相比,以下迭代方法具有以下优点:1)它将数字本身作为输入,2)避免了早期解决方案中的 object 复制(早期用于避免对输入的破坏性修改),3)是似乎是解决问题的更直接的方法。

from collections import Counter

def num_pairs(number, total=10):
    digits = Counter(int(c) for c in str(number))
    output = 0
    while True:
        x = next(digits.elements(), None)
        if x is None:
            return output
        digits[x] -= 1
        y = total - x
        if digits[y] > 0:
            output += 1
            digits[y] -= 1

print(num_pairs(734655))  # 3

An alternative way to solve the problem recursively is to convert the preceding iterative implementation to one that uses recursion in place of the loop, as shown in the example Python implementation below.递归解决问题的另一种方法是将前面的迭代实现转换为使用递归代替循环的实现,如下面的示例 Python 实现所示。 Some languages (eg, Scheme) would use tail call optimization here so that each recursive call would not use any additional stack space.一些语言(例如,Scheme)会在这里使用尾调用优化,这样每个递归调用就不会使用任何额外的堆栈空间。 This is not the case for Python.这不是 Python 的情况。

from collections import Counter

def num_pairs(number, total=10, _state=None):
    if _state is None:
        _state = {
            'digits': Counter(int(c) for c in str(number)),
            'result': 0
        }
    digits = _state['digits']
    x = next(digits.elements(), None)
    if x is None:
        return _state['result']
    digits[x] -= 1
    y = total - x
    if digits[y] > 0:
        _state['result'] += 1
        digits[y] -= 1
    return num_pairs(number, total, _state)

print(num_pairs(734655))  # 3

Additionally, a recursive solution could utilize sorting and binary search.此外,递归解决方案可以利用排序和二进制搜索。 First, sort the digits.首先,对数字进行排序。 For the first digit x , use binary search on the other digits to see if there is a y such that x + y equals the specified total.对于第一个数字x ,对其他数字使用二进制搜索以查看是否存在y使得x + y等于指定的总数。 If y is present, return 1 plus the recursively calculated number of pairs in the remaining sorted digits.如果y存在,则返回 1 加上剩余排序数字中递归计算的对数。 If not, return the recursively calculated number of pairs in the remaining digits.如果不是,则返回剩余数字中递归计算的对数。 The base case returns 0 when there are no digits remaining.当没有剩余数字时,基本情况返回 0。 Special-case handling is required for the case where x + y equals the specified total and x == y , to prevent over-counting.对于x + y等于指定总数x == y的情况,需要特殊情况处理,以防止过度计数。 Here's an example implementation in Python.这是 Python 中的示例实现。

from bisect import bisect_left

def num_pairs(digits, total=10, _sorted=False):
    if len(digits) == 1:
        return 0
    if not _sorted:
        digits = sorted(digits)
    x = digits[0]
    digits = digits[1:]
    y = total - x
    if x > y:
        return 0
    # Use binary search to check for y's location.
    idx = bisect_left(digits, y)
    pair_present = idx < len(digits) and digits[idx] == y
    # If x + y == total and x == y, pop y to prevent over-counting.
    if pair_present and x == y:
        digits = digits[1:]
    return pair_present + num_pairs(digits, total=total, _sorted=True)

number = 734655
print(num_pairs([int(c) for c in str(number)]))  # 3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM