2015-05-12 1 views
4

Итак, я пытаюсь написать программу, которая проходит всю возможную комбинацию боковых длин для трех сторон треугольника и печатает те, которые следуют за теоремой Пифагора (т. Е. SideA (sqr) + sideB (sqr) = hypotenuse (sqr)). Те, которые соответствуют, должны печатать. Однако математика не выполняет то, как она должна. Проблема, я думаю, заключается в том, как я настраивал свои циклы.Тест на теорему Пифагора не работает?

Мой вопрос в том, как мне это настроить? Поскольку у меня создалось впечатление, что для циклов выполняется следующим образом:

Самый дальний цикл проверяет, удовлетворено ли условие pythagorean. Если это так, он снова печатает результат, приращения и тесты. Когда условие не выполняется, оно переходит ко второму циклу, в котором тот же самый процесс повторяется, и в этот момент второй цикл переходит в третий, самый внутренний для цикла. Там он будет увеличиваться до 500, тестировать и печатать каждый применимый результат, и как только это будет сделано, он перейдет обратно в средний цикл. Средний цикл увеличивается, тесты снова повторяются, и как только условие не проверяется, код переходит в самый внутренний цикл, и процесс повторяется, только на этот раз изменяется переменная среднего цикла (т. Е. Тестируются новые наборы чисел.) Весь процесс повторяется до тех пор, пока цикл 2-го цикла не увеличится до 500, и в этот момент он переместится во внешний цикл, а процесс повторится. Самый внешний цикл увеличивается до тех пор, пока условие больше не будет удовлетворено, затем оно переносится в средний цикл, а две внутренние петли снова пройдут свою процедуру только на этот раз с измененной переменной внешнего цикла (т. Е. Снова проверит новые возможности).

любая помощь по этому вопросу будет оценена по достоинству. Мне бы хотелось двигаться дальше, но я чувствую, что эта концепция вложенного цикла очень важна для понимания, и я не хочу слишком коротко об этом говорить.

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 

int main(void) { 

    int sideA = 1; 
    int sideB = 1; 
    int hypotenuse = 1; 

    for (hypotenuse = 1; hypotenuse <= 500; hypotenuse++) { 
     if ((hypotenuse * hypotenuse) == (sideA * sideA + sideB * sideB)) { 
      printf("%d, %d, %d\n", sideA, sideB, hypotenuse); 
     } 

     else { 
      for (sideA = 1; sideA <= 500; hypotenuse++) { 
       if ((hypotenuse * hypotenuse) == (sideA * sideA + sideB * sideB)) { 
        printf("%d, %d, %d\n", sideA, sideB, hypotenuse); 
       } 

       else { 
        for (sideB = 1; sideB <= 500; sideB++) { 
         if ((hypotenuse * hypotenuse) == (sideA * sideA + sideB * sideB)) { 
          printf("%d, %d, %d\n", sideA, sideB, hypotenuse); 
         }  
        } 
       } 
      }   
     }   
    } 
} 
+0

Положить логику для тестирования на каждом уровне цикла - это не лучший способ сделать это - вместо этого вставьте три уровня вашего цикла и проверьте в цикле внутреннего цикла. –

+0

.. и вам вообще не нужен третий внутренний контур. Это на 100% определяется двумя первыми. –

ответ

3

Typo at for (sideA = 1; sideA <= 500; hypotenuse++).

Кроме того, чрезмерное количество ifs, вам не нужно ничто из этого.

#include <stdio.h> 

int main(void) 
{ 
    int sideA, sideB, hypotenuse; 

    for (hypotenuse = 1; hypotenuse <= 500; hypotenuse++) 
     for (sideA = 1; sideA <= 500; sideA++) 
      for (sideB = 1; sideB <= 500; sideB++) 
       if ((hypotenuse * hypotenuse) == (sideA * sideA + sideB * sideB)) 
        printf("%d, %d, %d\n", sideA, sideB, hypotenuse); 
} 

http://ideone.com/P01jxB

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

  1. После первого цикла, sideA и sideB используется первый if не будет 1 больше , они могут даже оказаться вне границ (501).
  2. Если логика падает на любой из этих if s, вы не будете запускать тесты для других значений.

Что касается производительности, обратите внимание, что этот вложенный цикл работает в общей сложности 125 миллионов раз (500 * 500 * 500). Это может быть оптимизировано во многих отношениях, в том числе с помощью пары функций Lib вы включены, но не используется, math.h:

#include <stdio.h> 
#include <math.h> 

int main(void) 
{ 
    int a, b; 
    for (a = 1; a <= 500; a++) 
     for (b = a; b <= 500; b++) // b starts from a, not 1 
     { 
      double h = sqrt(a * a + b * b); 

      if (h > 500.0) // hypotenus is bigger than 500, stop the loop 
       break; 

      if (fmod(h, 1) == 0.0) // only print if hypotenuse is an integer value 
      { 
       printf("%d, %d, %d\n", a, b, (int)h); 
       printf("%d, %d, %d\n", b, a, (int)h); // print both ways around, optional 
      } 
     } 
    return 0; 
} 

http://ideone.com/DZFa3s

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

+0

Вы даже представили рабочий пример. Хорошо сделано :) –

+1

Это может быть более эффективным с 'for (sideA = 1; sideA

+0

@WeatherVane Еще больше, если он просто рассчитал гипотенузу из 'sideA' и' sideB', также подразумевается, что инвертирование 'sideA' и' sideB' даст тот же результат для гипотенузы, но все эти оптимизации не являются неотъемлемой частью проблема. – Havenard

Смежные вопросы