被间接乘法算法困扰

时间:2018-12-19 02:12:25

标签: c++ c recursion iteration

在准备考试的同时,我发现了一个问题,要求使用间接乘法算法。

问题:

  

两个整数 p q 可以通过以下方法间接相乘。

     

如果期望乘积为 r (最初为0),则如果 q 为奇数,则 p 为   添加到 r q 的值减少1,   如果 q 甚至 p 被加倍并添加到 r 中,并且 q 减半(即 q < / em>变为 q / 2)

进一步指出,间接乘法用于直接乘法昂贵的数字计算机中

通过尝试几个小时,我设法找到了迭代算法和递归算法,但是它们并不完美。

迭代

int multiply(int p, int q){
    int r=0;
    while(q!=0){
        if(q%2==1){
            r += p;
            q--;
        }
        else{
            r += 2*p;
            q = q/2;
        }
    }
    return r;
}

递归

int multiplyRec(int p, int q){
    if(q==1)
        return p;
    if(q%2==1){
        return (p + multiplyRec(p, q-1));
    }
    else{
        return (2*p + multiplyRec(p, q/2));
    }
}

例如,当我将6乘以5时,两种算法的答案都是36,而必须是30。但是,如果我将其更改为30,则乘以1就会失败。

我正在上网,但找不到匹配项。 有人可以解释一下上述算法有什么问题吗?是否有错误或者有更好的方法来解决这些问题。

2 个答案:

答案 0 :(得分:1)

引号框中的算法错误。应该是:

  

如果期望乘积为r(最初为0),那么,如果q为奇数,则将p加到r上,并将q减1,如果q为偶数,则p加倍并且q减半(即q变成q / 2)

也就是说,当q为偶数时,只要将p加倍,就不要将其加到r。

它也缺少q == 0的隐式终止条件

这对应于简单的二进制长乘法-对于q中的每个1位,您将p左移1位的位置;对于q中的每个0位,您什么也不做。

通常写为

while (q != 0) {
    if (q & 1)  // q is odd
        r += p;
    p *= 2;
    q /= 2;
}

这是因为当q为奇数时,减去1将使它成为偶数,因此您可以立即执行将p加倍并将q减半的下一步。由于整数除法是四舍五入的,所以将奇数除以2也会隐式地将-1除。

答案 1 :(得分:1)

如果您遵循以下规则,而不是您声明的规则,该算法将可以正常工作:

  

如果预期乘积为r(最初为0),则如果q为奇数p加到r,如果q为偶数p被加倍且q被减半(即q变为q / 2)

示例代码:

int mult(int p,int q){

int r=0;

if(q%2==1)
{
    if(q!=1)
    {
        r+=p;
        //q--;
        return r*q;
    }

    r+=p;
    return r*q;
}

else if(q%2==0)
{
    if(q!=0)
    {
        p=p*2;
        r+=p;
        q=q/2;

        return r*q;
    }

    return 0;

}}