当一个或两个因素为负时,如何进行递归乘法?

时间:2012-10-05 07:05:40

标签: java

public static int multiply2(int num1, int num2) {
    if (num1 == 0 || num2 == 0) {
        return 0;
    }

    else {
        return num1 + multiply2(num1, num2 - 1);
    }

}

我刚刚意识到制作一个可以确定两个数字的乘积的程序会很有趣,其中一个或两个都是负数。我想用递归乘法(基本上重复加法)来做。有人可以帮帮我吗?谢谢!

8 个答案:

答案 0 :(得分:3)

if (num1 == 0 || num2 == 0) {
        return 0;
}

else if( num2 < 0 ) {
    return - num1 + multiply2(num1, num2 + 1);
}

else {
    return num1 + multiply2(num1, num2 - 1);
}

答案 1 :(得分:3)

else if (num1 < 0 || num2 < 0) {
    int signum1 = num1 < 0 ? -1 : 1;
    int signum2 = num2 < 0 ? -1 : 1;
    return signum1 * signum2 * multiply(signum1 * num1, signum2 * num2);
} else {

像这样的东西

注意:有一个signum功能,Math.abs可用于signum * num

答案 2 :(得分:1)

您将测试它是否为负数并减去而不是添加:

public static int multiply2(int num1, int num2) {
    if (num1 == 0 || num2 == 0) {
        return 0;
    }
    else if(num2 > 0){
        return num1 + multiply2(num1, num2 - 1);
    }
    else{
        return -num1 + multiply2(num1, num2 + 1);
    }
}

答案 3 :(得分:1)

如果数字是-ve,则需要添加。如果您发现我们只添加了第一个数字,那么我们必须达到0。因此,如果为肯定+1,那么如果为-1

,则为 else if (num2 < 0) return -num1 + multiply2(num1, num2 + 1); else return num1 + multiply2(num1, num2 - 1); System.out.println(multiply2(5, -6));-->-30 System.out.println(multiply2(5, 6));-->30
{{1}}

答案 4 :(得分:1)

与其在主递归部分中多次处理,不如将其作为边缘情况处理,并将其转换成常规情况,这是一个更好的主意,因为赋值和返回都不会发生,直到数学运算完成完成。 为此,我将y转换为正数,然后在结果返回负数时将函数的结果取整。

这是我的解决方法:

private static int product(int x, int y) {
    // Negative start edge case
    if (y < 0) {
        return -1 * product(x, y * -1);
    }

    // Edge case (only for speed)
    if (y == 0 || x == 0) {return 0;}

    // Base case
    if (y == 1) {
        return x;
    }

    // Recursion
    return x + product(x, y-1);
}

值得注意的是,即使没有0的情况,该方法仍然有效。在这种情况下,该方法只需要多做一些即可获得结果。

测试得出的结论是,该方法可以在参数为0和/或为负的情况下工作。

答案 5 :(得分:0)

public static int multiply2(int num1, int num2) {
    if (num1 == 0 || num2 == 0) {
        return 0;
    }

    else {
        int sign2=(int)(Math.abs(num2)/num2);
        return sign2*num1 + multiply2(num1,num2-sign2);
    }

}

答案 6 :(得分:0)

David Wallace的答案很好,但如果输入是(1,124)或(-1,124),则递归深度(方法调用自身的次数)将为123,效率不高。我建议添加几行来测试1或-1。这是一个完整的例子:

public class Multiply {

    public static void main(String[] args) {

        System.out.print("product = " + multiply(1, 124) );
    }

    public static int multiply(int x, int y) {
        System.out.println("Multiply called: x = " + x + ", y = " + y);

        if (x == 0 || y == 0) {
            System.out.println("Zero case: x = " + x + ", y = " + y);
            return 0;
        }

        else if (x == 1 && y > 0) {
            return y;
        }

        else if (y == 1 && x > 0) {
            return x;
        }

        else if ( x == -1 && y > 0) {
            return -y;
        }

        else if ( y == -1 && x > 0) {
            return -x;
        }

        else if( y == -1 ) {
            System.out.println("y is == -1");
            return -x;
        }

        else if( x == -1 ) {
            System.out.println("x is == -1");
            return -y;
        }

        else if( y < 0 ) {
            System.out.println("y is < 0");
            return -x + multiply(x, y + 1);
        }

        else { 
            System.out.println("Last case: x = " + x + ", y = " + y);
            return x + multiply(x, y - 1);
        }
    }
}

输出:

Multiply called: x = 1, y = 124
product = 124

答案 7 :(得分:0)

好的,所以我实际上是在做这个作业。 递归解决方案实现 - 或使用 - 确定需要继续的基本案例。现在,你可能会说,“这对地球意味着什么?”好吧,用外行人的话来说,这意味着我们可以简化我们的代码(在现实世界中,节省我们的软件一些开销) - 稍后我会解释。现在,问题的一部分是理解一些基本数学,即负数加负数是负数减去正数(-1 + -1 = -2 )取决于您所说的数学老师(我们将在下面的代码中看到它们发挥作用)。

现在, 有一些争论,在这里。关于我将在稍后写的内容。

这是我的代码:

public static int multiply(int a, int b)
{
    if (a == 0) 
    {
        return result;
    } 
    else if (a < 0) // Here, we only test to see whether the first param.  
                    // is a negative
    {
        return -b + multiply(a + 1, b); // Here, remember, neg. + neg. is a neg.
    }                                   // so we force b to be negative.
    else 
    {
        result = result + b;
        return multiply(Math.abs(a - 1), b);
    }
}

请注意,有两件事做得不同,在这里:

  1. 由于第一段中的数学原理,上面的代码不测试第二个参数以查看第二个参数是否为负(a < 0)(参见粗体文字在第一段)。基本上,如果我知道我乘以( y )乘以负数( -n ),我知道我正在接受 -n 并添加它一起 y 次数;因此,如果multiplicand or multiplier是否定的,我知道我可以接受其中任何一个数字,将数字设为负数,然后一遍又一遍地将数字添加到自身,例如-3 * 7可以写成(-3)+( - 3)+( - 3)+( - 3)......等等 OR ( - 7)+( - 7)+( -7)

  2. 现在正在进行辩论:以上代码不会测试第二个数字(int b)是否为0,即乘以0。为什么?嗯,这是个人选择(有点)。这里的争论必须权衡某事物的相对重要性:每种选择的开销(或者是否运行等于零的测试)。如果我们测试以查看一边是否为零,则每次进行乘法的递归调用时,代码必须计算表达式;但是,如果我们测试等于零,那么代码会将一堆零加在一起 n 次。实际上,这两种方法“权衡”相同 - 因此,为了节省内存,我省略了代码。