алгоритм имитации умножения путем сложения

Как разработать алгоритм для имитации умножения путем сложения. введите два целых числа. они могут быть нулевыми, положительными или отрицательными.


person KawaiKx    schedule 05.07.2011    source источник


Ответы (4)


какой-то псевдокод:

function multiply(x, y)
  if abs(x) = x and abs(y) = y or abs(x) <> x and abs(y) <> y then sign = 'plus'
  if abs(x) = x and abs(y) <> y or abs(x) <> x and abs(y) = y then sign = 'minus'

 res = 0
 for i = 0 to abs(y)
  res = res + abs(x)
 end

 if sign = 'plus' return res
    else return -1 * res

end function
person Tudor Constantin    schedule 05.07.2011
comment
Это очень простое решение.. соответствующее моему решению.. довольно простое - person KawaiKx; 06.07.2011
comment
по принципу KISS (Keep It Stupid Simple) :)) - person Tudor Constantin; 06.07.2011

Как насчет этого для целых чисел:

int multiply(int a, int b)
{
    int product = 0;
    int i;
    if ( b > 0 )
    {
        for(i = 0; i < b ; i++)
        {
            product += a;
        }
    }
    else
    {
        for(i = 0; i > b ; i--)
        {
            product -= a;
        }
    }

    return product;
}
person Jonathan Ramos    schedule 25.09.2017

Я попал сюда, потому что искал алгоритм умножения без использования операции *. Все, что я вижу здесь, это просто добавление или вычитание числа n раз. Это O(n), и это нормально, но...

Если у вас есть bitwise shift операций, вы можете получить алгоритм O(log n) для умножения.

Вот мой псевдокод:

function mul(n, x)
    if n < 0 then   # 'n' cannot be negative
        n := -n
        x := -x
    endif

    y := 0
    while n != 0 do
        if n % 2 == 0 then
            x := x << 1     # x := x + x
            n := n >> 1     # n := n / 2
        else
            y := y + x
            x := x << 1     # x := x + x
            n := n - 1      # n := (n-1)/2
            n := n >> 1
        endif
    endwhile

    return y                # y = n * x
end

Помните, что функция выше для mul(1000000, 2) — это O(log 1000000), а для mul(2, 1000000) — только O(log 2).

Конечно, вы получите те же результаты, но имейте в виду, что порядок параметров в вызове функции имеет значение.

Изменить: боковое примечание для использования n % 2

Реализация n % 2 с использованием bitwise shift

Это довольно просто. Сначала разделите n на 2, затем умножьте n на 2 и проверьте, изменилось ли n. Псевдокод:

function is_even(n)
    n_original := n
    n := n >> 1        # n := n / 2
    n := n << 1        # n := n * 2
    if n = n_original then
        return true    # n is even
    else
        return false   # n is not even
    endif
end

Реализация n % 2 с использованием bitwise and

function is_even(n)
    if n and 1 = 0 then
        return true
    else
        return false
    endif
end
person Kyriet    schedule 09.01.2020

person    schedule
comment
вопрос касается имитации умножения без использования функции умножения... вы можете использовать только сложение.. - person KawaiKx; 05.07.2011
comment
Это рекурсивная функция. Если вы пройдёте код, то увидите, что он выполняет только сложение (и многократно вызывает сам себя). - person Dr. Acula; 05.07.2011
comment
я думаю, он имел в виду умножение ваших знаков "-" - person jemmanuel; 05.07.2011
comment
Технически вам не нужно проверять случай, когда a==1. - person Mikola; 05.07.2011
comment
@mikola, поскольку он использует рекурсивный алгоритм, я думаю, что он использует случай a == 1 в качестве базового случая .... без которого его код вернул бы 0, несмотря ни на что :) - person jemmanuel; 05.07.2011
comment
@enjay: Поскольку фактическое умножение не используется, досрочное спасение для == 1 не требуется. В случае, если a == 1, будет вызвано else, и будет возвращено b + умножить ( 0, b ) -> b + 0, и все в порядке. Следовательно, случай a==1 не нужен. - person LiKao; 05.07.2011
comment
@Saurabh: умножение на знаки - можно легко убрать, написав вместо него 0-... . - person LiKao; 05.07.2011
comment
Я понял .. очень умное и элегантное решение ... это синтаксис python? - person KawaiKx; 05.07.2011
comment
@ Dr.Acula, как вы думаете рекурсивно? Мне кажется, это очень сложный навык :-) - person KawaiKx; 07.07.2011
comment
@Saurabh Вот мои рекомендации по рекурсивному мышлению: 1. Рассмотрите все ваши базовые случаи. 2. Рекурсивные вызовы должны выполняться для меньшего элемента или подмножества. 3. Верить в правильность рекурсивного вызова. Если вы знаете, что рассмотрели все свои базовые случаи и точно рассмотрели, что пытаетесь сделать для рекурсивного шага, то рекурсия сделает все остальное. Рекурсия - это сложная вещь, чтобы сначала обернуть голову. Однако, как только вы поймете и будете использовать его чаще, концептуализация вашей проблемы станет намного проще, потому что вы сможете рассматривать каждую часть по отдельности. - person Dr. Acula; 08.07.2011