Все возможные пифагорейские тройки
Вот вопрос
Найдите все пифагорейские тройки для стороны1, стороны2 и гипотенузы не более 500. Используйте тройную вложенность для циклов, которые пробуют возможности.
Ниже моя попытка
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int side1 = 0;
int side2 = 0;
int rightSide = 0;
cout << "Right Side" << setw(10) << "Side1" << setw(10) << "Side2" << endl;
for(int i=1;i<=500;i++)
{
side1++;
//cout << side1 << endl;
for(int a=1;a<=500;a++)
{
side2++;
//cout << "side 2 " << side2 << endl;
for(int c=1;c<=500;c++)
{
rightSide++;
int rightSideSqr = rightSide*rightSide;
int side1Sqr = side1*side1;
int side2Sqr = side2*side2;
if(rightSideSqr == side1Sqr+side2Sqr)
{
cout << rightSideSqr << setw(15) << side1 << setw(10) << side2 << endl;
}
}
}
}
}
Но это не дает успеха, похоже на бесконечный цикл. Пожалуйста помоги.
Пожалуйста, обратите внимание: я новичок в C++, я изучаю его самостоятельно. И это не домашнее задание, я сформулировал проблему, потому что это лучший способ выразить проблему.
РЕДАКТИРОВАТЬ
Правая сторона сторона1 сторона2
RUN SUCCESSFUL (общее время: 1сек)
РЕДАКТИРОВАТЬ 2
Рабочий код
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
//int side1 = 0;
//int side2 = 0;
//int rightSide = 0;
cout << "Right Side" << setw(10) << "Side1" << setw(10) << "Side2" << endl;
for(int i=1;i<=500;i++)
{
//side1++;
//cout << side1 << endl;
for(int a=1;a<=500;a++)
{
//side2++;
//cout << "side 2 " << side2 << endl;
for(int c=1;c<=500;c++)
{
//rightSide++;
int rightSideSqr = c*c;
int side1Sqr = i*i;
int side2Sqr = a*a;
if(rightSideSqr == (side1Sqr+side2Sqr))
{
cout << rightSideSqr << setw(15) << i << setw(10) << a << endl;
}
}
}
}
}
2 ответа
Это не бесконечный цикл, это просто очень медленный конечный цикл. Ввод / вывод медленный - вы печатаете 500*500 = 250 000 строк текста в cout
оператор в среднем цикле, и вывод 250 000 строк текста на консоль очень, очень медленный. Если вы удалите этот оператор печати, он будет выполняться намного быстрее.
Во-вторых, у вас есть ошибка в вашей логике. Переменные side1
, side2
, а также rightSide
никогда не сбрасывайте в 0 в соответствующее время, поэтому они просто продолжают увеличиваться за пределы их предполагаемых значений. Попробуйте сбросить их до 0 или просто использовать счетчики циклов вместо дополнительных переменных, подобных этому.
Кроме того, из проблем, указанных @Adam Rosenfield. Программа не будет быстро заканчиваться с такими 3 циклами, если предел будет увеличен немного выше.
Первое наблюдение заключается в том, что вам не нужен 3-й внутренний цикл, так как гипотенуза может быть рассчитана и сравнена. Вычислите гипотенузу с двух сторон, превратите ее в целое число и проверьте, сохраняется ли равенство Пифагора.
Вы можете сделать еще несколько замечаний: две стороны являются взаимозаменяемыми, поэтому нам нужно только зациклить до sqrt (500 2/2) (переход на другую сторону просто перевернет стороны). Для 2-го внутреннего цикла для другой стороны прямоугольного треугольника, так как мы знаем верхний предел, мы можем сократить количество циклов, выполнив цикл до sqrt (500 2 - side1 2).
Псевдокод, а не код C (^
в коде C есть XOR, но я использую ^
в псевдокоде ниже для обозначения мощности). round()
будет округлять до ближайшего целого числа (вам может потребоваться реализовать это). Верхний предел для 2 циклов может быть кэширован непосредственно перед входом в цикл, так как их значение не изменится во время цикла:
for (side1 = 1; side1 <= round(sqrt(500^2 / 2)); side1++) {
for (side2 = side1; side2 <= round(sqrt(500^2 - i^2)); side2++) {
hypo = round(sqrt(side1^2 + side2^2))
if (hypo^2 == side1^2 + side2^2) {
printResult
}
}
}