2015-03-10 2 views
4

Я очень новичок в C++ и пытаюсь создать функцию для реализации евклидова алгоритма, который возвращает наибольший общий делитель для двух целых входов.C++ Самый большой общий делитель

Текущий подход, который я принимаю, продолжает терпеть крах - можете ли вы помочь мне понять, почему?

int main() {  
    int a = 0; 
    int b = 0; 

    cin >> a; 
    cin >> b; 

    do { 
     if (a > b) a = a % b; 
     else if (a < b) b = b % a; 
     else if (a == b) break; 
    } while ((a || b) != 0); 

    return 0; 
} 

Спасибо,

Дэвид

ответ

8
while ((a || b) != 0); 

это не так. Он должен быть

while (a != 0 && b != 0); 

На стороне записки, алгоритм Евклида может быть сжато реализован рекурсивно:

int gcd(int a, int b) 
{ 
    return b == 0 ? a : gcd(b, a%b); 
} 
+0

спасибо Армен, изучая рекурсию следующий;) –

+1

http://www.nullptr.me/2012/01/07/c-template-metaprogramming/ есть несколько реализаций GCD. также рекурсивный. – Alex

3

Ваш термин (a || b) != 0 не рассосется, как вы ожидаете.
Что вы хотите сделать, это (a != 0) && (b != 0)
Или как Cheers and hth. - Alf предлагает только a && b.

+2

Почему не просто 'a && b' –

+0

Спасибо, вы правы, я пропустил этот вариант. – FireRain

+0

@ Cheersandhth.-Alf Это может быть менее читаемым/понятным для новых учеников C++. –

1

Ваше состояние, а это неправильно. Вы не можете это упростить.

while ((a || b) != 0); 

Должно быть так.

while ((a != 0) && (b != 0)); 

Кстати, вы могли бы сделать гораздо более легкий подход. Что-то вроде этого

int main() { 

int a, b, r; 

cin >> a; 
cin >> b; 

while (b != 0) { 
    r = a % b; 
    a = b; 
    b = r; 
} 

cout << "The GCD is " << a << endl; 

} 

И есть другой способ, он не требует кода алгоритма. Просто используйте библиотеку алгоритмов libstdC++. Libstdc++

+0

сделал ту же программу ... вы также могли бы написать while (b) вместо while (b! = 0). Но в любом случае .. очень крутое использование евклидова алгоритма! – moldovean

1

Давайте поближе рассмотрим ваши коды, может быть, вам интересно, что делает while ((a || b) != 0)?

Теперь мы должны оценить (a || b) != 0. В C/C++ оценки начинается справа налево, но () имеет более высокий приоритет, поэтому во время выполнения мы имеем:

bool r1 = a || b; // intermediate result 
bool r2 = r1 != 0; 
while(r2); 

Шаги:

  • a || b оценивается в true когда либо a или b имеют отличное от нуля значение.
  • r1 будет отливают в целом
    • true становится 1
    • false становится 0
  • r1 != 0 вычисляется и приводит к булеву значению (true или false)
  • while решает, должен ли он цикл или нет.
Смежные вопросы