我正在解决递归问题,即计算一个数字中连续8的总数。例如:
input: 8801 output: 2
input: 801 output: 0
input: 888 output: 3
input: 88088018 output:4
我无法弄清楚将信息传递给下一个递归调用的逻辑,即前一个数字是否为8。
我不想要代码,但我需要逻辑方面的帮助。对于迭代解决方案,我可以使用标志变量,但在递归中如何执行标记变量在迭代解决方案中执行的工作。此外,它不是任何作业的一部分。这只是我想到的,因为我正在尝试使用递归来练习编码。
答案 0 :(得分:3)
一个典型的解决方案是在你的函数中添加一个新参数来传递"标记"州。此参数通常称为accumulator。如果您正在使用允许嵌套函数的语言,您通常需要定义一个外部函数,该函数接受实际参数,然后定义一个内部递归函数,其中累加器作为参数。这是Scheme here中的一个例子。
答案 1 :(得分:0)
您可以使用此功能逐位扫描您的号码
int totalConsecutive8(int digit, boolean last)
而boolean last表示最后一位(即digit - 1
)是否为8。
例如,在最后一个例子88088018中,从数字0开始,boolean last为false - >数字1,因为最后一位是8,所以最后是真的...
Java中的代码
public int numberOfConsecutive8(int val){
String number = "" + val;
return totalConsecutive8(number, 0, false, false);
}
public int totalConsecutive8(String number, int digit, boolean last, boolean first){
if(digit == number.length()){
return 0;
}
int result = 0;
if(number.charAt(digit) == '8'){
if(last){
if(first){
result += 2 + totalConsecutive8(number, digit + 1, true, false);
}else{
result += 1 + totalConsecutive8(number, digit + 1, true, false);
}
}else{
result += totalConsecutive8(number, digit + 1, true, true);
}
}else{
result += totalConsecutive8(number, digit + 1, false, false);
}
return result;
}
巴马尔提出的方法:
int totalConsecutive8(int number, boolean last , boolean first){
if(number == 0){
return 0;
}
int result = 0;
if(number % 10 == 8){
if(last){
if(first){
result += 2 + totalConsecutive8(number/10, true , false){
}else{
result += 1 + totalConsecutive8(number/10, true , false){
}
} else{
result += totalConsecutive8(number/10, true , true){
}
}else{
result += totalConsecutive8(number/10, false , false){
}
return result;
}
答案 2 :(得分:0)
当你专注于递归时,我会提到它的一个细节和好处,根本不需要传递任何额外的参数或计数调用。
您可以使用修改后的参数从内部调用函数 - 比如在函数中检查字符串减去一个数字 - 然后再次调用它直到字符串变空。
可能是多次 - 嵌套调用。
<强> [UPDATE] 强> 下面是Python中的示例,详细说明更具可读性。 我们用字符串,连续8s的当前链调用我们的函数,如果当前字符串的第一个字符串不是'8'(已经知道总连续8s
)则刷新def f8_trace(s, chainlen=0, total=0, indent=0):
print ' '*indent, "invoked with s='%s', chainlen=%d, total=%d" % (s,chainlen, total)
if len(s) == 0:
if chainlen>1:
total += chainlen
retval = total
else:
if s[0] == '8':
chainlen += 1
else:
if chainlen>1:
total += chainlen
chainlen = 0
retval = f8_trace(s[1:],chainlen,total,indent+1)
print ' '*indent, 'returns %d' % (retval)
return retval
s = 'abc888d88e8f888'
print f8_trace( s )
invoked with s='abc888d88e8f888', chainlen=0, total=0
invoked with s='bc888d88e8f888', chainlen=0, total=0
invoked with s='c888d88e8f888', chainlen=0, total=0
invoked with s='888d88e8f888', chainlen=0, total=0
invoked with s='88d88e8f888', chainlen=1, total=0
invoked with s='8d88e8f888', chainlen=2, total=0
invoked with s='d88e8f888', chainlen=3, total=0
invoked with s='88e8f888', chainlen=0, total=3
invoked with s='8e8f888', chainlen=1, total=3
invoked with s='e8f888', chainlen=2, total=3
invoked with s='8f888', chainlen=0, total=5
invoked with s='f888', chainlen=1, total=5
invoked with s='888', chainlen=0, total=5
invoked with s='88', chainlen=1, total=5
invoked with s='8', chainlen=2, total=5
invoked with s='', chainlen=3, total=5
returns 8
returns 8
returns 8
returns 8
returns 8
returns 8
returns 8
returns 8
returns 8
returns 8
returns 8
returns 8
returns 8
returns 8
returns 8
returns 8
8
答案 3 :(得分:0)
这里出现上述问题的伪代码: -
int max = 0;
void cal_eight(char ch[],int i,int count) {
if(ch[i]=='\0') {
max = maximum(max,count);
}
else if(ch[i]=='8') {
cal_eight(ch,i+1,count+1);
}
else {
max = maximum(max,count);
cal_eight(ch,i+1,0);
}
}
call :- cal_eight(ch,0,0)
答案 4 :(得分:0)
这是Haskell中的一个例子,Haskell是一种通常与递归方法相关的语言。
xxs
代表字符串,x
和xs
松散意味着,&#34;第一项&#34;和&#34;其余的&#34; (所以在我们检查x
之后,我们将xs
,字符串的其余部分传递给下一个函数调用。)
previous
表示前一个数字为8.我希望其余的代码看起来更直接且不言自明。警卫|
就像必要的一样#34;如果&#34;条款(例如,如果之前的话......)。
f xxs first8 previous count
| null xxs = count
| previous = if x == 8
then f xs 0 True (count + first8 + 1)
else g
| otherwise = if x == 8
then f xs 1 True count
else g
where x:xs = xxs
g = f xs 0 False count
输出:
*Main> f [8,0,1] 0 False 0
0
*Main> f [8,8,8] 0 False 0
3
*Main> f [8,8,0,8,8,0,1,8] 0 False 0
4