【问题标题】:Pythagorean Theorem test not working?勾股定理测试不起作用?
【发布时间】:2015-07-23 17:14:28
【问题描述】:

所以我正在尝试编写一个程序,该程序循环遍历三角形 3 条边的所有可能的边长组合,并打印出符合勾股定理的那些(即 sideA(sqr) + sideB(sqr) =斜边(sqr))。那些匹配的,它应该打印。然而,数学并没有按应有的方式执行。我认为问题在于我如何设置循环。

那么我的问题是,我应该如何设置它?因为我的印象是 for 循环以以下方式执行:

最外层的循环会检查是否满足勾股条件。如果是,它会打印结果、递增并再次测试。当条件不满足时,它将转移到第二个 for 循环,重复相同的过程,此时第二个循环转移到第三个,最里面的 for 循环。在那里,它会一直增加到 500,测试并打印每个适用的结果,一旦完成,它将转移回中间循环。中间循环递增,再次测试,一旦条件不检查,代码转移到最内层循环并重复该过程,只是这次改变中间循环变量(即,正在测试新的数字集。 ) 整个过程重复,直到第二个 for 循环一直递增到 500,此时它转移到最外面的循环,并且整个过程重复。最外层循环递增,直到不再满足条件,然后转移到中间循环,并且 2 个内部循环再次执行它们的过程,只是这次使用更改的外部 for 循环变量(即再次测试新的可能性)。

对此的任何和所有帮助将不胜感激。我很想继续前进,但我觉得嵌套循环的这个概念确实是理解的关键,我不想在这方面卖掉自己。

#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);
                        }      
                    }   
                }
            }           
        }        
    }
}

【问题讨论】:

  • 在循环的每一层放置测试逻辑并不是最好的方法 - 相反,嵌套循环的 3 层并检查最内层的循环。
  • ..你根本不需要第三个内循环。 100% 由前两个决定。

标签: c loops for-loop


【解决方案1】:

for (sideA = 1; sideA &lt;= 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. 在第一个循环之后,第一个 if 使用的 sideAsideB 将不再是 1,它们甚至可能超出范围 (501)。
  2. 如果逻辑落在这些 ifs 中的任何一个上,您将不会运行其他值的测试。

至于性能,请注意这个嵌套循环总共运行了 1.25 亿 次 (500 * 500 * 500)。这可以通过多种方式进行优化,包括使用您包含但未使用的库的几个函数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,000 个循环。

【讨论】:

  • 使用for (sideA = 1; sideA &lt; hypotenuse; sideA++) for (sideB = hypotenuse-sideA; sideB &lt; hypotenuse; sideB++) 可能会更有效,但 +1。
  • @WeatherVane 更重要的是,如果它只是从 sideAsideB 计算斜边,这也暗示反转 sideAsideB 将得到相同的斜边结果,但所有这些优化不是当前问题的一部分。
  • 我会做一些不同的整数测试:int s1 = a*a + b*b, h1 = int(0.5 + sqrt((double)s1); if (h1 * h1 == s1) ...
  • 伙计,我的生意一团糟……非常感谢大家的帮助,非常感谢。现在这一切实际上都非常简单明了。
猜你喜欢
  • 2021-09-20
  • 1970-01-01
  • 1970-01-01
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
  • 2019-10-08
  • 1970-01-01
相关资源
最近更新 更多