我分配了一个函数,该函数将2个整数相乘并且不使用*或'-'。我只能使用'+''/'和'%'。
我注意到很多人都在使用换档方法,但是我不能不使用它,因为我们还没有学到它。
在没有1 while循环的情况下,我可以做的很多事情就是,窍门应该是在n log n或log n运行时效率上。
没有列出任何数组,尽管我仍然看不到任何使用它们的方法。
有什么可能的方法吗?
答案 0 :(得分:5)
此算法为O(nlogn)。分而治之。
double Multiply(int n, double x) {
if (n == 0)
return 0.0;
if (n == 1)
return x;
double a = Multiply(n/2, x);
if ((n%2) == 1)
return x + a + a;
return a + a;
}
注意:该代码尚未经过测试。我无法在iPad上编译C代码。
答案 1 :(得分:4)
根据Ian Abbot的评论,此处 是实现目标的一种<嬉皮士方式:
double Multiply(int n, double x) {
if (n == 0) return 0.0;
else return x / (1.0 / n);
}
或者,如果您想要更简洁的单线:
double Multiply(int n, double x) { return n ? x / (1.0 / n) : 0.0; }
对Ian的“答案”所做的一项更改(但恕我直言,这是一项重要更改)是因为int
参数被检查为零,因为这更加可靠比尝试测试double
(或float
)的精确度为 零。
注意:原始问题指定数字为“整数和双精度”,因此我给出了相应答案。
答案 2 :(得分:3)
这是另一个快速且肮脏的解决方案,没有递归性,符合OP的要求:
int Multiply(int a, int b)
{
int result = 0;
while (b > 0)
{
if (b % 2 != 0)
result += a;
a += a;
b /= 2;
}
return result;
}
与chmike的答案中的算法基本相同。
我并不担心复杂性,但是看起来很像O(log n)。
b绝对不能与负值一起使用,我将其保留为练习。
答案 3 :(得分:2)
只是为了扩展Jabberwocky的答案(OP应该完全接受),这里有几种处理负数的方法。
如果需要获得正确的结果符号,则第一种方法会在主循环之前使用-
作弊:
int Multiply(int a, int b)
{
int result = 0;
if (b < 0)
a = -a; /* Cheat! But at least its a unary operation. */
while (b != 0)
{
if (b % 2 != 0)
result += a;
a += a;
b /= 2;
}
return result;
}
第二种方法利用unsigned int
进行2的补码运算。从技术上讲,这存在一个小问题,因为可以根据C标准规则将正确的否定结果替换为实现定义的结果。无论如何,对于大多数以2的补码表示有符号整数的实现来说,这都不是问题。
int Multiply(int a_, int b_)
{
unsigned int a = a_;
unsigned int b = b_;
unsigned int result = 0;
while (b != 0)
{
if (b % 2 != 0)
result += a;
a += a;
b /= 2;
}
// N.B. negative result might be replaced with implementation-defined result!
return (int)result;
}
此外:忽略有符号整数的处理,这种乘法方法也称为Russian peasant method。
答案 4 :(得分:1)
这是使用移位和加法的另一种方法。它与其他一些答案有很多共同点,但是在可能的地方使用按位运算,并且对负数的处理略有不同(它还避免了Ian Abbot承认的“一元负”可能是“作弊”):
int mult(int a, int b)
{
int answer = 0;
int minus = 0;
if (a < 0) {
minus ^= 1;
a ^= -1; ++a; // Negate (without using *) - assuming 2s complement representation ...
}
if (b < 0) {
minus ^= 1;
b ^= -1; ++b; // ... where "-x" is the BIT INVERSE of "x" PLUS ONE
}
while (a) {
if (a & 1) answer += b; // If the nth bit of "a" is set we add "b << n"
b <<= 1; // But shift up (multiply by 2)
a >>= 1; // Bit shift down (divide by 2)
}
if (minus) { // ONE (and only ONE) number was negative ...
answer ^= -1; ++answer; // ... so we negate our answer!
}
return answer;
}
这将适用于负数(一个或两个),但不能处理整数溢出(但是,本机z = x * y
也不会这样做)。
请随时要求进一步的澄清和/或解释。