递归函数,用于添加数字序列的总和及其总和

时间:2009-08-21 12:47:05

标签: c algorithm recursion

这是一个采访问题:

  

给定n个数字的序列(n可以是任何数字,假设此问题的n <= 100),例如说。 11,23,9,17,20,8,5,6。 问题是在C 中编写递归函数以添加序列中的每个数字以获得总和。如果此总和超过一位数,则如果总和超过一位,则再次对数字求和,然后再次对数字求和。按照此过程,直到总和减少到一位数。现在添加在过程中获得的所有总和以输出最终总和。

为了说明,采用上述顺序:11,23,9,17,20,8,5,6

SUM(11, 23, 9, 17, 20, 8, 5, 6) = 99 =&gt; SUM(9, 9) = 18 =&gt; SUM(1, 8) = 9

现在添加所有获得的总和,即SUM(99, 18, 9) = 126&lt; ==应该是输出。

请注意,该功能应该是C 中的递归函数。

7 个答案:

答案 0 :(得分:1)

不确定C,但算法看起来与此类似。

SUM(1,2,... n)= 1 + SUM(2,... n)等等得到总数,然后在找到最终数字超过一位数后重复。 / p>

答案 1 :(得分:0)

这是一个可以用作指南的Erlang实现

-module('summation').  
-export([start/1]).  

sumlist(List)->
  lists:foldl(fun(X, Sum) -> X + Sum end, 0, List). << Inherently recursive

num_to_list(Value) ->
  Str = integer_to_list(Value),
  lists:map(fun(X) -> X - 48 end, Str).  << Inherently recursive

accumulate([_H], List) ->
  io:fwrite("~w~n", [List]),
  List;
accumulate(Value, List) ->
  Tmp = sumlist(Value),
  accumulate(num_to_list(Tmp), [Tmp|List]).  % << Recurse here

start(List)->
  Value = accumulate(List, []),
  sumlist(Value).

测试

25> c(summation).
{ok,summation}
26> summation:start([11, 23, 9, 17, 20, 8, 5, 6]).
[9,18,99]
126
27>

答案 2 :(得分:0)

#include "stdafx.h"

#include <stdio.h>

#include <stdlib.h>

const int n = 8;

int sumDigits(int x)
{
    int d = 0;

    while (x != 0)
    {
        d += x % 10;
        x /= 10;
    }

    return d;
}

int sumArr(int* a, int start)
{
    return (start == n)? 0: a[start] + sumArr(a, start + 1);
}

int sum(int x)
{
    return (x < 10)? x: x + sum(sumDigits(x));
}

int main(int argc, _TCHAR* argv[])
{
    int* a = new int[n];
    a[0] = 11; a[1] = 23; a[2] = 9; a[3] = 17; a[4] = 20; a[5] = 8; a[6] = 5; a[7] = 6;
    //for (int i = 0; i < n; i++) a[i] = rand() % 100;
    //for (int i = 0; i < n; i++) printf("a[%d] = %d\n", i, a[i]);

    printf("sum = %d\n", sum(sumArr(a, 0)));

    return 0;
}

这输出: sum = 126

答案 3 :(得分:0)

这是Scala实现:

def sum(lst: List[Int]): Int = {
    val sum1 = lst.reduceLeft(_+_)
    println(sum1)
    sum1 match {
       case nb if nb < 10 => sum1
       case _ => {
            val lst2 = sum1.toString.toList.map(_.toString).map(Integer.parseInt(_))
            sum1 + sum(lst2)
       }
    }

}

val lst = List(11, 23, 9, 17, 20, 8, 5, 6)
val totalSum = sum(lst)
println(totalSum)

结果:

99
18
9
126

我真的开始喜欢,Scala是多么简洁。

答案 4 :(得分:0)

正如其他人所说:这里的重点是理解递归。

我们可以使用递归的3个地方:

  • 对积分数中的所有数字求和:

    sum_digital :: (Integral a) => a -> a
    sum_digital d
       | d < 10     = d
       | otherwise  = d `mod` 10 + sum_digital (d `div` 10)
    
  • 从起始值和规则链接所有总和

    chain :: (Integral a) => a -> [a]
    chain a 
        | a < 10 = [a]
        | otherwise = a : chain (sum_digital a)
    
  • 最后一个。列表总和

    mySum :: (Integral a) => [a]-> a
    mySum [] = 0
    mySum (x:xs) = x + mySum xs 
    

将所有这些放在一起:

*Main> mySum $ chain $ mySum [11, 23, 9, 17, 20, 8, 5, 6]    
126

C版本留给你作为练习:)

答案 5 :(得分:0)

我只是想将这一个添加到77v's answer,以便尽可能地使所有内容变为硬核。我知道这已经是一年前了,他的C ++解决方案已经非常好了。但我真的没有乐趣,虽然我可以将最后一个名为sumDigits的函数转换为递归。所以为了摆脱厌倦,这里是:

long sumDigits(long x, long d = 0)
{
    if (x != 0)
    {
        d = x % 10;
        return d + sumDigits(x / 10, d);
    }
    else
        return 0;
}

它是相同的,7行长并接受一个参数。请注意,第二个默认为0.它用作递归本身的内存。用户可以完全忽略该第二个参数。该函数的使用方式与77v的实现方式相同。事实上你可以直接用这个替换他的功能。因此,在他的解决方案递归的基础上使所有功能。这使得已经很棒的作品更加精彩!大声笑! :d

答案 6 :(得分:0)

#include <iostream>
using namespace std;

class RecursiveSum {
public:
    int nDigits(int a) {
        int d = 0;
        while (a > 0) {
            d++;
            a /= 10;
        }
        return d;
    }

    long sum(int *arr, int b, int e, int s) {
        if (!arr)
            return 0;
        if (b < e) {
            s += arr[b++];
            return sum(arr, b, e, s);
        } else { // b >= e
            if (s < 10)
                return s;

            int nd = nDigits(s);
            int* narr = new int[nd];
            long n = s, itr = 0;
            while (n > 0) {
                narr[itr++] = n % 10;
                n /= 10;
            }

            s += sum(narr, 0, nd, 0);
            delete[] narr;

            return s;
        }
    }

};