寻找模式的递归解决方案

时间:2014-06-13 03:02:02

标签: algorithm recursion logic

我正在解决递归问题,即计算一个数字中连续8的总数。例如:

input: 8801 output: 2
input: 801 output: 0
input: 888 output: 3
input: 88088018 output:4

我无法弄清楚将信息传递给下一个递归调用的逻辑,即前一个数字是否为8。

我不想要代码,但我需要逻辑方面的帮助。对于迭代解决方案,我可以使用标志变量,但在递归中如何执行标记变量在迭代解决方案中执行的工作。此外,它不是任何作业的一部分。这只是我想到的,因为我正在尝试使用递归来练习编码。

5 个答案:

答案 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代表字符串,xxs松散意味着,&#34;第一项&#34;和&#34;其余的&#34; (所以在我们检查x之后,我们将xs,字符串的其余部分传递给下一个函数调用。)

设置为True的

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