【问题标题】:Stucked up with Indirect Multiplication Algorithm被间接乘法算法困住了
【发布时间】:2019-05-19 11:56:48
【问题描述】:

当我准备考试时,我发现了一个问题,要求提供一种间接乘法算法。

问题:

pq两个整数可以通过下面的方法间接相乘。

如果预期乘积为 r(最初为 0),则如果 q 为奇数,则将 p 添加到 r 并且 q 减 1,如果 q 为偶数,则 p 加倍并且 q 减半(即 q 变为 q/2) 如果 q 是偶数 p 加倍并添加到 r 并且 q 减半(即 q 变成 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 就会失败。

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

【问题讨论】:

  • “p is doubled”部分应该被视为对p存储值的修改(结果随后添加到r)。相反,您将两次 p 添加到 r 而不更新 p
  • 您告诉我们您的算法有哪些不完善之处,我们可以帮助您找出原因。 IE。请描述什么是错误的,什么意外发生,什么没有发生,崩溃,挂起,错误的结果,在哪些情况下?
  • qp = (q-1)p + p 是有道理的,但第二个条件(q/2)(2p) + 2p = 2p+qp != pq 可以为我解释一下吗?
  • @Yunnosch 编辑了问题'

标签: c++ c recursion iteration


【解决方案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。

【讨论】:

  • 您想强调甚至解释其中的区别吗?
  • 部分解释:为什么我不用乘以2?想象一下我一直只除以二?答案:在某些时候,即使是 2 的幂也会达到 1,因此在任何情况下都会发生一个最终加法 ...
  • 不,不是。而你这么认为的事实是支持我的提议,以使差异更加明显。
  • @BinaraMedawatta 事实是 - 问题中描述的算法根本是错误 - 无论您是按原样从问题表中引用还是自己引入了错误......但是如果您发现确实引用了 1:1,那么您应该联系教授/考官/...并提示他/她注意错误。
【解决方案2】:

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

如果预期乘积是 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;

}}

【讨论】:

  • @BinaraMedawatta 不客气,但从技术上讲,这个问题是错误的。如果您将 q 的值减少 1 ,它将永远不会给您正确的结果。希望我能帮到你。
  • 一旦得到奇数,给出的算法将永远不会终止。您的示例代码只是使用*(内置乘法)来避免这种情况,但实际上并不能真正乘法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-18
  • 1970-01-01
  • 2019-04-30
  • 2020-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多