从num1到num2的最短路径(在C ++中)

时间:2013-01-26 12:24:50

标签: c++ recursion

我需要编写一个函数(在C ++中)得到两个整数(> 0)(n1,n2)。 我只能做两件事:

  • 将1添加到n1。
  • 将n1乘以2。

该函数返回从n1到n2的最短路径的步数。 你能给我一些想法吗?

谢谢!

P.S。 如果不可能,则函数返回-1。

这里我尝试了什么:

if (n1<n2)
{
    n1++;
    if ((n1)*2<=n2)
        return 2+f(n1*2,n2);
    else
        return 1+f(n1,n2);
}

5 个答案:

答案 0 :(得分:3)

我认为最好解决问题:用这两种方式从n2转到n1:

  • 减去1
  • 除以2(仅当结果为整数时)

通过这种方式,当您第一次尝试将数字除以2时,您可以找到最大的步骤,如果不可能,则减去1(之后进行除法)。执行此操作直到达到n1(或更低的值,之后您只能使用'减少步骤',因此基本上已经知道所需的步骤数量)

我想你可以自己实现这个算法......

答案 1 :(得分:2)

一次只考虑一步。

让我们说n1startn2end

如果您已经end,那么您不需要任何步骤。 如果start大于end,那么你就无法做到。

否则你有两个选择..

  • start添加1并递归重复此过程 - 将步骤数存储为add
  • start乘以2并递归重复此过程 - 将步骤数存储为mult

如果两者都可以,那么两者中最低的就是你的答案。

如果您在删除代码之前获得了我的代码,我希望您会花时间逐步完成它,否则您可以尝试将其写出来......大约需要一分钟左右..

P.S。对于大量步骤,您可能希望将其实现为尾递归算法以防止<insert name of the website here>

p.p.s这是一个非常低效的算法,因为它探索了每个分支。您可以尝试改进它,并尝试减少所需的分支数量,也许只有在不做的时候才添加..

答案 2 :(得分:1)

如上所述,你可以将问题转化为一个问题,即从n2到n1反向进入贪婪的选择。答案当然是一样的。

但可以进行更多观察:

  • 如果换档会导致数字太低,那么从现在开始必须采取的步骤数为current - n1,您不必逐个计算所有这些步骤。
  • 如果移位会导致的数字太低,无论您当前是奇数还是偶数,都可以随时移动(但添加最低位到所采取的步数,因为它会采取一步)
  • 使用n1和n2中最高设置位的位置,可以一次执行多个移位(将移位量和你移出的位的汉明重量加到步数上)。您可以执行的班次数为bsr(n2) - bsr(n1) - 1,但请注意边缘情况。这并不总是最大转换步数,它可能需要多一个(但不会超过)。

答案 3 :(得分:0)

int numOfSteps(int n1, int n2) {
    if (n1 > n2) return -1;
    if (n1 == n2) return 0;
    int result = 0;
    while (n1 * 2 <= n2) {
            n1 *= 2;
            result ++;
    }
    while (n1 < n2) {
            n1 ++;
            result ++;
    }
    return result;
}

答案 4 :(得分:0)

我解决了! (我向我的朋友请求建议......)

这是代码:

int f(unsigned int n1, unsigned int n2){

int num1,num2;

if (n1==n2)
        return 0;
if (n1>n2)
    return -1;
num1=f(n1+1,n2)+1;
num2=f(n1*2,n2)+1;
return min(num1,num2);}

这是“min”:

int min (unsigned int n1, unsigned int n2){
if (n1*n2==0) //If one of them is zero then (n1+n2) return the non-zero
              //number.
    return n1+n2;
else
    if (n1>n2)
        return n2;
    else
        return n1;}

谢谢!!