Как преобразовать этот код Python в C ++

0

У меня есть алгоритм работы в Python, который я хочу преобразовать в C++:

def gcd(a, b):    
    if (a % b == 0):
        return b
    else:
        return gcd(b, a % b)

def solution(N, M):
    lcm = N * M / gcd(N, M)
    return lcm / M

У меня проблема с большими входными значениями, поскольку кратное N и M вызывает переполнение целого числа и использование long для хранения его значения, похоже, не помогает, если я не делаю что-то неправильно.

Вот мой текущий код:

int gcd(int a, int b)
{
    if (a % b == 0)
        return b;
    else
        return gcd(b, a % b);
}

int solution(int N, int M) {

    // Calculate greatest common divisor
    int g = gcd(N, M);

    // Calculate the least common multiple
    long m = N * M;
    int lcm = m / g;

    return lcm / M;
}
  • 0
    Какие ценности вы предоставляете для solution ?
  • 0
    Оба N и M находятся в пределах диапазона (1, 1 000 000 000).
Показать ещё 2 комментария
Теги:
integer
overflow

3 ответа

1
Лучший ответ

Вы вычисляете g=gcd(N,M), затем m=N*M, затем lcm=m/g и, наконец, возвращаем lcm/M То же самое, что и возвращение N/gcd(N,M). Вам не нужны эти промежуточные вычисления. Избавься от них. Теперь нет проблем с переполнением (если только M = 0, то есть вы не защищаете).

int solution(int N, int M) {
   if (M == 0) {
      handle_error();
   }
   else {
      return N / gcd(N,M);
   }
}
  • 0
    Это все хорошо замечено! Я ненавижу пропустить такие вещи. Обработка ошибок не требуется, так как M и N гарантированно будут по крайней мере 1.
  • 0
    Хотя ответ избегает проблемы в решении OP, это не выдвигает на первый план проблему в этом. Лучше знать реальную проблему, которая существует в решении OP. Ошибка очень распространенная, о которой часто забывают.
Показать ещё 1 комментарий
1

Для начала измените:

long m = N * M;
int lcm = m / g;

Для того, чтобы:

long long m = (long long)N * M;
int lcm = (int)(m / g);

В общем, вы можете также изменить каждый int в вашем коде на unsigned long long...

Но если у вас есть класс BigInt, вы можете использовать его вместо этого.

Вот один из них бесплатно: http://planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=9735&lngWId=3

Он сохраняет естественное количество любых мыслимых размеров и поддерживает все арифметические операторы, представленные в C++.

  • 0
    Я пробовал несколько комбинаций этого подхода, и он все еще не работает.
  • 0
    Вы не сказали, почему этот подход не работает, Мариан. Вы получаете ошибку компиляции с long long ? Это не часть C ++ 03, но это довольно стандартное расширение. Это часть C ++ 11.
Показать ещё 3 комментария
-1

Проблема заключается в long m = N*M. Умножение происходит только в виде 32-битных целых чисел. Поскольку оба имеют тип int, происходит переполнение.

Коррекция long long m = (long long)N*M

Ещё вопросы

Сообщество Overcoder
Наверх
Меню