在 Python 中 Num1 之后出现 Num2 的范围 (1,n) 与递归



新手在这里。我在math.stackoverflow上发现了一个关于如何计算4在1到10000(34,340,但也包括324,3274)的3之后出现的次数的问题。我写了一个解决它的代码,但我想知道是否有一种更简单、更干净的方法来用递归来编写它,用于任何数字作为 n

def fours_after_threes(n):
    List = []
    for i in range(1,n,1):
        buf = ''
        buf += str(i)
        List.append(buf)
    cn = 0
    for el in List:
        if len(el) < 2:
            pass
        elif len(el) == 2:
            if el[0] == "3" and el[1] == "4":
                cn+=1
        elif len(el) == 3:
            if el[0] == "3" and el[1] == "4":
                cn+=1
            elif el[0] == "3" and el[2] == "4":
                cn+=1
            elif el[1] == "3" and el[2] == "4":
                cn+=1
        elif len(el) == 4:
            if el[0] == "3" and el[1] == "4":
                cn+=1
            elif el[0] == "3" and el[2] == "4":
                cn+=1
            elif el[0] == "3" and el[3] == "4":
                cn+=1
            elif el[1] == "3" and el[3] == "4":
                cn+=1
            elif el[1] == "3" and el[2] == "4":
                cn+=1
            elif el[2] == "3" and el[3] == "4":
                cn+=1
    return cn
print fours_after_threes(10000)

>>> 
523

这就是我坚持的代码。如何使用范围的"其余"?或者,也许您有更好的想法,如何解决任何给定范围和任何给定数字的问题?

while len(List)>0:
    for el in List:
        if "3" in range(0,len(el)-1) and "4" in **range(1,...**
            cn+=1
            List.remove(List[0])
            return function_name(1000)
        else:
            List.remove(List[0])
            return function_name(1000)
print fours_after_threes(1,10000,3,4)

下面是一个简短的函数,如果 4 之前有一个 3(数字 = "34"),并且数字也作为字符串传入,则返回 True:

def in_string(digits, number):
    if not number:    # no more digits in number?
        return False  # all done
    digit = number[0]     # get the leading digit
    number = number[1:]   # leave the remaining digits in number
    if digit == digits[0]:    # found a digit in the sequence?
        digits = digits[1:]   # leave the remaining digits
        if not digits:        # no more digits in sequence?
            return True       # all done
    return in_string(digits, number)    # recursion
c = 0
for i in range(10000):
    if in_string("34", str(i)):
        c += 1
print c

结果是 523

我想出了这个:

def rec(buffer_list, index, found):
    if index == len(buffer_list):
        return found
    num_str = str(buffer_list[index])
    three_index = -1
    four_index = -1
    if len(num_str) < 2:
        return rec(buffer_list, index+1, found)
    for i in num_str:
        if i == '3':
            three_index = num_str.index(i)
        if i == '4':
            four_index = num_str.index(i)
    if 0 <= three_index < four_index:
        found += 1
        return rec(buffer_list, index+1, found)
    else:
        return rec(buffer_list, index+1, found)

def find_three_four(n):
    found = 0
    numbers = range(1, n, 1)
    total = rec(numbers, 0, 0)
    print total
find_three_four(100)

它不是很优雅,但它似乎正在工作,前 100 个数字 (34) 给出 1,500 个数字给出 22。Python 无法处理超过 999 次调用的递归,因此在进行递归时请记住这一点

我已经尝试过使用字符串并通过第一次出现的"3"拆分字符串。它不像正则表达式示例那样优雅,但它显然比手动比较字符串的每个数字要好。

def test(lst):
    counter = 0
    # Test every element of the list
    for i in lst:
        # Convert it to a string and split it by the *first* occurence of '3'
        i = str(i).split('3', 1)
        # Check if there was a 3 in it by comparing the length of the result
        if len(i) > 1:
            # Now check if a 4 is in the second part (meaning after the 3)
            if '4' in i[1]:
                counter += 1
    return counter
test(range(10000))
# returns 523

这不是递归,而是迭代。基于此示例,使用不同的"数字"进行扩展应该很容易。


经过一番思考,我真的找到了一种递归的方法:

def test(lst, numbers):
    counter = 0
    for i in lst:
        # Start recursion for the current number and the numbers we are looking for
        counter += testnumber(str(i), numbers)
    return counter
def testnumber(number, remainingnumbers):
    if len(remainingnumbers) == 0:
        # No number remaining to look for - valid
        return 1
    if len(number) == 0:
        # Number is exhausted but we haven't found that combination
        return 0
    if number[0] == remainingnumbers[0]:
        # Check the rest of the number without the found first number
        # because we have found a match!
        return testnumber(number[1:], remainingnumbers[1:])
    else:
        # Check for the rest of the number... there was no match this recursion
        return testnumber(number[1:], remainingnumbers)
test(range(10000), ['3', '4'])

它可以检查任意组合['1', '2']也是可能的,甚至可以['1', '2', '3', '4', '5']即使后者会导致零计数。

最新更新