Для классических интервью вопроса «Как вы выполняете целочисленное умножение без оператора умножения?», Самый простой ответ, конечно, следующий алгоритм линейного времени в C:Какова временная сложность этого алгоритма умножения?
int mult(int multiplicand, int multiplier)
{
for (int i = 1; i < multiplier; i++)
{
multiplicand += multiplicand;
}
return multiplicand;
}
Конечно, есть более быстрый алгоритм. Если мы воспользуемся свойством, что смещение бита влево эквивалентно умножению на 2 на мощность числа сдвинутых битов, мы можем смещать бит до ближайшей мощности 2 и использовать наш предыдущий алгоритм для добавления оттуда. Таким образом, наш код теперь будет выглядеть примерно так:
#include <math.h>
int log2(double n)
{
return log(n)/log(2);
}
int mult(int multiplicand, int multiplier)
{
int nearest_power = 2^(floor(log2(multiplier)));
multiplicand << nearest_power;
for (int i = nearest_power; i < multiplier; i++)
{
multiplicand += multiplicand;
}
return multiplicand;
}
У меня возникли проблемы с определением сложной сложности этого алгоритма. Я не считаю, что O(n - 2^(floor(log2(n))))
- это правильный способ выразить это, хотя (я думаю?) Это технически правильно. Может ли кто-нибудь объяснить это?
multipicand + = multipicand; – Mikeb
Исправлено - спасибо, что указали это. – rybosome
Ваш первый алгоритм не является алгоритмом умножения, но результатом является 'multipicant * pow (2, множитель)', no? –