为什么这个方法需要递归?

时间:2012-02-12 04:45:20

标签: c# algorithm

一时兴起,我决定回去寻求认证,从98-361,软件开发基础开始。 (我为自己做的比其他任何事都要多。我想填补我的知识空白。)

在本书的最初阶段,他们在精通评估部分介绍了这个有趣的场景:

  

您正在开发一个实用功能库   应用。你需要编写一个带整数和的方法   计算其中的有效位数。您需要创建递归程序   解决这个问题。你会怎么写这样的?   程序

我发现自己在这种情况下陷入困境。如果我正确理解“有效数字”,那么对于将整数的有效数字计算为递归的函数则没有必要。并且,任何坚持认为它是递归的建筑师都应该对他进行检查。

或者我没有得到它?我在这里完全错过了什么吗?根据我的理解,有效数字是数字的数字,从左边开始,向右行进,不包括任何前导零。

在什么条件下这需要递归? (对我来说,这个练习的重点是学习新事物。有人给我一个骨头。)

编辑:我不想回答问题。我可以自己解决这个问题。在我看来,通过对字符串中的字符进行简单的foreach循环,可以更容易地解决这个“问题”。

最终修改

鉴于以下令人敬畏的海报的圣人建议,这是我提出的解决问题的简单解决方案。 (尽管我可能有些疑虑。)

using System;

class Program
{
    static void Main(string[] args)
    {

        var values = new[] { 5, 15, 150, 250, 2500, 25051, 255500005, -10, -1005 };
        foreach (var value in values)
        {
            Console.WriteLine("Signficiant digits for {0} is {1}.", value, SignificantDigits(value));
        }
    }

    public static int SignificantDigits(int n)
    {
        if (n == 0)
        {
            return 0;
        }

        return 1 + SignificantDigits((int)(n / 10));
    }
}

3 个答案:

答案 0 :(得分:4)

这种算法没有 need 是递归的。但这里的意图不是编写真实世界的代码,而是确保理解递归。

既然你说你不是在代码之后,我会在这里小心,但我需要提供某些东西来比较解决方案的复杂性,所以我将使用伪代码。递归解决方案可能类似于:

def sigDigits (n):
    # Handle negative numbers.

    if n < 0:
        return sigDigits (-n)

    # 0..9 is one significant digit.

    if n < 10:
        return 1

    # Otherwise it's one plus the count in n/10 (truncated).

    return 1 + sigDigits (n / 10)

你是对的,它同样可以作为迭代。

def sigDigits (n):
    # Handle negative numbers.

    if n < 0:
        n = -n

    # All numbers have at least one significant digit.

    digits = 1

    # Then we add one and divide by ten (truncated), until we get low enough.

    while n > 9:
        n = n / 10
        digits = digits + 1

    return digits

有一些(通常是数学弯曲的,包括我自己)认为递归算法在它们适合的地方更加优雅(例如“解决方案搜索空间”减少得非常快,以免炸掉你的堆栈)。

我质疑这个特定案例的适用性,因为迭代解决方案不是太复杂,但是提问者必须提供一些问题而且这个问题相对容易解决

并且,根据您的编辑:

  

...可以通过字符串中字符的简单foreach循环轻松解决

你没有拥有字符串,你有一个整数。我不怀疑你可以将转换成一个字符串然后计算字符,但这似乎是一种迂回的方式。

答案 1 :(得分:2)

需要 是递归的。只是问题是要求你编写一个递归实现,大概是为了测试你对递归函数如何工作的理解。

答案 2 :(得分:1)

这似乎是一个非常强迫的例子。问题可以通过更简单的迭代算法来解决。

很多教学资源很难提供何时使用递归的有用示例。从技术上讲,你从不需要来使用它,但是对于一大类(主要是算法)问题,它可以真正简化事情。

例如,考虑binary tree上的任何操作。由于二叉树的物理结构是递归的,因此对其进行操作的算法也是自然递归的。您还可以编写命令式算法来操作二叉树,但递归算法更易于编写和理解。