在准备考试的同时,我发现了一个问题,要求使用间接乘法算法。
问题:
两个整数 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就会失败。
我正在上网,但找不到匹配项。 有人可以解释一下上述算法有什么问题吗?是否有错误或者有更好的方法来解决这些问题。
答案 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;
}}