Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.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# - Fatal编程技术网

C# 提高递归序列的计算速度

C# 提高递归序列的计算速度,c#,C#,我正试图用c#解决这个问题(如下) 对于自然数,可以使用以下过程: 在给定数字的右侧键入0 在给定编号的右侧键入编号4 将数字除以2 如果给出数字55,是否可以获得以下数字:2003、2004、2005、2006、2007 ((()((()((如果我们获得数字32,那么我们可以获得其中任何一个数字:2003,2004,2005,2006,2007) 我们可以通过28个步骤找到解决方案 所以我写了这段代码: static void Main(string[] args) { lo

我正试图用c#解决这个问题(如下)

对于自然数,可以使用以下过程:
在给定数字的右侧键入0
在给定编号的右侧键入编号4
将数字除以2
如果给出数字55,是否可以获得以下数字:2003、2004、2005、2006、2007
((()((()((如果我们获得数字32,那么我们可以获得其中任何一个数字:2003,2004,2005,2006,2007)
我们可以通过28个步骤找到解决方案

所以我写了这段代码:

   static void Main(string[] args)
  {
    long number = 550, goal = 32;
    int count = 0;
    bool flag = false;
    find(number, goal, count, flag);
    Console.WriteLine("Done");
    Console.ReadKey();
 }
 static bool find(long number, long goal, int count, bool flag)
 {
     if(number==goal) { Console.WriteLine(number); return true; }
     if(count ==28 && number != goal) { return false;}
     else
     {
         flag =find(number*10, goal, count+1, flag); 
         if (flag == true) {  Console.WriteLine(number); return flag; }
         flag = find(number * 10 + 4, goal, count + 1, flag);
          if (flag == true) { Console.WriteLine(number); return flag;  }
         if (number % 2 == 0) {
            flag= find(number / 2, goal, count + 1, flag);
           if (flag == true) { Console.WriteLine(number); return flag; 
         } }
         return flag;
         }
       }

任何人都可以加快递归过程

您的实现很简单,但很幼稚。它将经历所有的可能性,直到找到匹配项。经过一点思考,您实际上可以完成大部分计算

当您的递归代码执行时,每个递归调用分为3个路径,最大可能为3^28不同的可能性。这是最坏的情况,当方法的结果为false时。一旦找到第一个路径,您的代码就会解析,但很有可能会浪费大量时间萨里的计算

我将以您的数字为例,以便我能够清楚地说明:

假设我做了以下调用:find(550,32,0,false)

在某个时间点上,您的程序将沿着它运行的路径运行 会不断地把550乘以10,但为什么还要一直把它乘以10呢 如果32小于550

在另一个时间点,您的程序将沿着它运行的路径运行 将550乘以10,然后继续加4。但是像以前一样,为什么 当目标变小时,是否继续向上

这是最后的结论:

number=传入参数number的当前值

Let返回=剩余的递归调用数。(28-当前递归调用#)

让maxDivisor等于2^x。这是当前值可以除以的最大值

最小未来数=number/maxdivisior

基本上,smallestFuture是从 当前递归调用。它是通过连续除以 当前数乘以2,直到递归计数达到28。然后,如果 最小的未来仍大于目标数,则 计算当前路径下的计算没有意义

下面是我写的代码。函数调用被修改了,因为我认为使用flag参数没有意义。如果您愿意,请随意添加它

static bool find(long number, long goal, int count)
{
    if (number == goal)
    {
        Console.WriteLine(number);
        return true;
    }

    if (count == 28 && number != goal)
        return false;

    int remIteration = 28 - count;
    long maxDivisor = (long)Math.Pow(2, remIteration);
    long smallestFuture = number / maxDivisor;

    if (smallestFuture > goal)
        return false;

    if (smallestFuture == goal)
    {
        Console.WriteLine(number);
        return true;
    }

    long newNumber = number * 10;
    int nexCount = count + 1;

    if (find(newNumber, goal, nexCount) || find(newNumber + 4, goal, nexCount))
    {
        Console.WriteLine(number);
        return true;
    }

    if (number % 2 == 0)
    {
        if (find(number / 2, goal, nexCount))
        {
            Console.WriteLine(number);
            return true;
        }
    }

    return false;
}
不幸的是,我现在没有足够的时间使用解决这个问题,但它肯定会提供比我的代码更好的性能。请注意,我的代码与您的代码一样,打印它检测到的第一条可能路径,而不是最佳路径