C# 用于反转整数位数的递归函数
我的目标是编写一个递归程序来反转整数的位数。当我测试第一个元素时,代码正常工作。但是,对于其他两种情况,它不起作用,例如,它用于C# 用于反转整数位数的递归函数,c#,recursion,digit,C#,Recursion,Digit,我的目标是编写一个递归程序来反转整数的位数。当我测试第一个元素时,代码正常工作。但是,对于其他两种情况,它不起作用,例如,它用于反向(456)打印321654,用于反向(731)打印321654137。 我认为问题在于公共静态变量已还原 有人能帮我理解这个问题并解决它吗 using System; public class Program { public static void Main(string[] args) { reverse(123);
反向(456)
打印321654,用于反向(731)
打印321654137。
我认为问题在于公共静态变量已还原
有人能帮我理解这个问题并解决它吗
using System;
public class Program
{
public static void Main(string[] args)
{
reverse(123);
reverse(456);
reverse(731);
}
public static int reverted=0;
public static void reverse(int number)
{
if (number!=0)
{
int remainder = number % 10;
reverted = (reverted*10)+remainder;
reverse(number/10);
}
else
Console.WriteLine(reverted);
}
}
试试我的方法:
public static int reverse(int number, int result = 0, int reminder = 0)
{
if (number == 0)
{
return result * 10 + reminder;
}
return reverse(number / 10, result * 10 + reminder, number % 10);
}
只需调用方法,如reverse(123)
。另外两个参数result
和remement
是可选的,因为它们有一个默认值
编辑:
以下是上述代码的简明版本:
public static int reverse(int number, int result = 0)
{
if (number == 0)
{
return result;
}
return reverse(number / 10, result * 10 + number % 10);
}
或使用三元运算符:
public static int reverse(int number, int result = 0)
{
return number == 0 ? result : reverse(number / 10, result * 10 + number % 10);
}
我的目标是编写一个递归程序来反转整数的位数
因为这是一个行业中没有人希望达到的目标,所以很有可能这是一个班级的目标。特别是,没有一个明智的人会用递归解决这个问题,即使他们有这个问题。这是教递归的一个糟糕的问题,因为非递归的解决方案非常简单
您不太了解递归的可能性也很大。从某种意义上说,这是一个很好的练习,因为它需要使用一种称为累加器的特殊技术来实现递归解决方案
此外,您的解决方案,即使您修复了错误,也不会产生所需的数量。它打印出来,这是完全不同的。我们希望能够产生结果,而不仅仅是展示结果
(这就引出了一个有趣的问题,即如何处理int
中的数字,但其反面不适合,比如1000000009
。让我们暂时忽略这些问题。)
让我们从基础开始。每个递归方法都具有相同的结构:
- 我们在基本情况下吗?如果是,请返回结果
- 我们不在基本情况下
- 把问题分解成更小的问题
- 递归地解决每个问题
- 结合解决方案来解决更大的问题
- 返回结果
- 从0到9的任何非负数的倒数就是它本身
- 把这个数字除以10得到一个较小的数字,15
- 把较小的数字倒过来——51
- 将原始数字的低阶数字附加为反向较小数字的高阶数字,751---等等,我们到底怎么做
number
为0
。然后ReverseHelper
返回0
,很好。零起作用
假设number
是3
。然后我们调用ReverseHelper(3,0)
,它调用ReverseHelper(0,3)
,它返回3
。一位数字起作用
假设number
为35
。我们调用ReverseHelper(35,0)
,它调用ReverseHelper(3,5)
,它调用ReverseHelper(0,53)
,它返回53
。两位数就行了
等等
练习:有一种简单的方法来处理反转整数的问题,如果反转不适合整数;这是什么
你看,我希望这项技术为什么被称为使用累加器。随着递归的进行,期望的结果逐渐累积,然后在递归到达其基本情况时返回
现在,请注意此技术与原始程序的关系使用静态字段作为累加器。永远不要那样做!曾经递归方法的正确性不应依赖于外部状态相反,将要递归使用的值向下传递到对助手方法的递归调用中。
仔细研究这项技术。这是一种编写递归程序的强大技术。在函数式语言中,这种操作称为fold
或reduce
;从中寻找更多的灵感。在C#中,它被称为Aggregate
,用于生成序列的汇总结果
使用累加器的递归模式是:
- 我们在基本情况下吗?如果是,则从累加器返回结果
- 我们不在基本情况下
- 把问题分解成更小的问题
- 通过在递归调用中将有关解决方案的信息累积到累加器中,以递归方式解决每个问题
- 结合解决方案来解决更大的问题
- 返回结果
static int ReverseHelper(int number, int accumulator) =>
number == 0 ?
accumulator :
ReverseHelper(number / 10, accumulator * 10 + number % 10);
让我们把它改写成一句话:
static int ReverseHelper(int number, int accumulator)
{
if (number == 0)
return accumulator;
else
return ReverseHelper(number / 10, accumulator * 10 + number % 10);
}
}
现在,让我们为所有子表达式创建解释变量:
static int ReverseHelper(int number, int accumulator)
{
if (number == 0)
return accumulator;
else
{
int newNumber = number / 10;
int newAccumulator = accumulator * 10 + number % 10;
return ReverseHelper(newNumber, newAccumulator);
}
}
到目前为止还不错。但现在我们注意到,我们可以把整个事情变成一个循环
static int ReverseHelper(int number, int accumulator)
{
while (true)
{
if (number == 0)
return accumulator;
else
{
int newNumber = number / 10;
int newAccumulator = accumulator * 10 + number % 10;
number = newNumber;
accumulator = newAccumulator;
// And now the loop starts over!
}
}
}
当然,我们看到它现在有了直接的非递归sol的形式
static int ReverseHelper(int number, int accumulator)
{
while (true)
{
if (number == 0)
return accumulator;
else
{
int newNumber = number / 10;
int newAccumulator = accumulator * 10 + number % 10;
number = newNumber;
accumulator = newAccumulator;
// And now the loop starts over!
}
}
}
public static int ReverseRecursive(int number)
{
int remainder = number % 10;
number = number / 10;
if (number < 1)
return remainder;
return ReverseRecursive(number) + remainder * Convert.ToInt32(Math.Pow(10, number.ToString().Length));
}