一时兴起,我决定回去寻求认证,从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));
}
}
答案 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上的任何操作。由于二叉树的物理结构是递归的,因此对其进行操作的算法也是自然递归的。您还可以编写命令式算法来操作二叉树,但递归算法更易于编写和理解。