Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于反转整数位数的递归函数_C#_Recursion_Digit - Fatal编程技术网

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的任何非负数的倒数就是它本身
递归情况是什么?假设我们有157个

  • 把这个数字除以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
,用于生成序列的汇总结果

使用累加器的递归模式是:

  • 我们在基本情况下吗?如果是,则从累加器返回结果
  • 我们不在基本情况下
  • 把问题分解成更小的问题
  • 通过在递归调用中将有关解决方案的信息累积到累加器中,以递归方式解决每个问题
  • 结合解决方案来解决更大的问题
  • 返回结果
为什么这项技术如此有价值?在C#中,这不太重要,但在尾部递归函数语言中,编译器通常可以将使用累加器的递归方法优化为比非尾部递归方法更高效的代码,因此这是需要研究的其他问题

它在C#中很有价值,因为使用累加器的尾部递归方法可以通过简单的程序转换过程轻松地转换为非递归方法

让我们看看如何。我们有:

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));
    }