如何编写一个取int
值的递归函数并返回连续序列最长的数字?
例如,f(1122333)
返回3,f(1223)
返回2
我不知道如何处理这个问题,而且我对一般的递归都不熟悉。
答案 0 :(得分:1)
像这样的东西。没有测试过。考虑一下很有意思。
伪代码:
(假设整数除法)
Def number helperLongest(number myNum):
Return longest(myNum, -1, 0, -1, 0)
Def number longest(number myNum,number prevLongest, number numOfPrevLong, number currentLongest,number numOfLongest):
If (myNum/10 < 1) //base case
If (myNum == currentLongest)
numOfLongest++
Else //deal with corner case of < 10 input
If (numOfLongest > numOfPrevLong)
prevLongest = currentLongest
numOfPrevLongest = numOfLongest
currentLongest = myNum
numOfLongest = 1
return (numOfLongest>numOfPrevLong)?currentLongest:prevLongest
Else //recurse
if(myNum%10 == currentLongest)
numOfLongest++;
Else //have to break the chain
if (numOfLongest > numOfPrevLongest)
prevLongest = currentLongest
numOfPrevLongest = numOfLongest
currentLongest = myNum%10
numOfLongest = 1
myNewNum = myNum/10;
return longest(myNewNum,prevLongest,numOfPrevLong,currentLongest,numberOfLongest);
用文字表示:从头开始逐个数字。如果当前的最后一个数字与之前的数字匹配,则递增计数器。如果它没有,并且它大于之前的最大值,请将其保存。将当前数字重置为当前最后一位数字并重置计数器。砍掉最后一位数字。将较小的数字和所有这些信息反馈回函数,直到您得到最后一位数(原始数字中的第一个数字)。将当前计数器与存储的最大值进行比较,然后返回较大的值。
一个注意事项:如果出现平局,将返回匹配数字的第一个子字符串(实际上是原始数字中的最后一个子字符串)。如果需要其他行为,请将两个>
与>=
互换。
答案 1 :(得分:1)
我能想到的最简单的事情就是通过tail recursion来做到这一点。在函数中,我将有一个私有函数,我们将用于递归。首先,我将整数转换为一个列表,其中每个数字被分隔为一个单独的元素。这个递归私有函数接受一个元素列表,我们正在调查的数字,保存最长连续序列的当前数字和一个描述我们已经看过多少次的计数。计数很重要,因为我们将计算遇到特定参考编号的次数。列表作为输入很重要,因为我们可以通过跳过此列表的第一个元素,为每个调用提供一个少一个元素的列表。最后,我们将只列出列表中的一个数字,即基本情况。
换句话说,对于任何递归算法,您需要 base 大小写,我们将停止并返回一些内容,以及递归大小写,我们需要在修改输入的情况下调用该函数。
基本情况是我们提供一个数字的数字。这意味着我们已达到数字的末尾。如果是这种情况,我们需要做的是检查此值是否等于当前被认为是连续的当前值。如果此值匹配,我们将当前连续计数增加1.如果此值超过当前最长连续计数,我们将返回此单个数字作为与最长连续序列相关的数字。如果没有,那么在我们决定进行此检查之前,我们只返回该值。
递归情况稍微复杂一些。给定我们正在查看的数字,我们检查该数字是否等于被视为连续流的一部分的数字。如果是,则将该数字的计数递增1,然后检查该计数是否大于当前最大连续计数。如果是,那么我们需要将当前最长值更新为此值并更新最长计数。如果这不匹配,我们会将计数重置为1 ,因为这是遇到此类型的第一个数字。要匹配的当前值将是此值,我们将递归我们提交从第二个索引开始的值列表的位置,并更新其他变量。
当我们继续递归并从第二个索引开始指定列表的值时,我们将有效地在列表中从开始直到最后到达列表的最后一个元素时进行线性搜索,这就是我们停下来。
不用多说,这就是我写的。该函数名为longest_consecutive_value
,它采用整数:
# Function that determines the value that has the longest consecutive sequence
def longest_consecutive_value(value):
# Recursive function
def longest_recursive(list_val, current_val, current_longest_val, longest_count, count):
# Base case
if len(list_val) == 1:
# If single digit is equal to the current value in question,
# increment count
if list_val[0] == current_val:
count += 1
# If current count is longer than the longest count, return
# the single digit
if count > longest_count:
return list_val[0]
# Else, return the current longest value
else:
return current_longest_val
# Recursive case
else:
# If the left most digit is equal to the current value in question...
if list_val[0] == current_val:
# Increment count
count += 1
# If count is larger than longest count...
if count > longest_count:
# Update current longest value
current_longest_val = list_val[0]
# Update longest count
longest_count = count
# If not equal, reset counter to 1
else:
count = 1
# Current value is the left most digit
current_val = list_val[0]
# Recurse on the modified parameters
return longest_recursive(list_val[1:], current_val, current_longest_val, longest_count, count)
# Set up - Convert the integer into a list of numbers
list_num = map(int, str(value))
# Call private recursive function with initial values
return longest_recursive(list_num, list_num[0], list_num[0], 0, 0)
以下是一些示例案例(使用IPython):
In [4]: longest_consecutive_value(1122333)
Out[4]: 3
In [5]: longest_consecutive_value(11223)
Out[5]: 1
In [6]: longest_consecutive_value(11223334444555555)
Out[6]: 5
In [7]: longest_consecutive_value(11111111122)
Out[7]: 1
In [8]: longest_consecutive_value(1122334444)
Out[8]: 4
请注意,如果有多个数字共享相同数量的连续数字,则只输出产生该连续数字长度的第一个数字。正如Ron Thompson在其帖子中所述,如果您希望最近或最后一个满足要求的连续数字,那么在检查计数时请使用>=
而不是>