多语言展示
当前在线:1728今日阅读:155今日分享:35

C语言求N以内的勾股数方法详解

用C语言代码求N以内的勾股数(勾股数是正整数),这里我们不算重复的,使用穷举法。这篇经验会提供代码及详细说明。首先我会展示运行结果,然后给出代码,最后会对代码中初学者可能会有的疑问做一些解答。
工具/原料

任何一款C语言IDE

一、结果及代码展示
1

首先我展示一下运行结果,我这里N设为1000

3

变量a,b,c就是代表三个欲求的勾股数;N是欲求勾股数的范围,我给的例子中是1000以内;n是用来计数有多少个的,没有需要可自行修改不用。用 unsigned int定义是勾股数都是正整数,用这个能算更大范围内的数,不是必要的。

二、可能有的疑问的解答
1

下面对我想到可能会有的一些问题做出解答,对这个算法有兴趣或者有疑问的往下看吧。

2

1、为什么判断是否是勾股数时只判断了“a*a + b*b == c*c”,而不是“a*a + b*b == c*c || a*a+c*c==b*b || b*b+c*c==a*a”(为了便于后面说明,前者简称方式一,后者简称方式二)?答:我们本意是找到勾股数而没有重复的,打个比方,我们希望结果里有个3,4,5就行了,而不希望除了它还有3,5,4、4,5,3、5,3,4等等。如果判断是用了方式二,这些结果都会出现,在本代码中,使用方式二判断做了无用功。(在本代码中,只改判断条件为后者结果并不变,不会出现重复的项,但这是代码中其他地方的功劳,具体往下看)。

3

可能有的小伙伴喜欢追寻真理,把判断条件改成方式二运行发现并没有像我说的那样出现重复项,这是因为在前面for循环那里初始值的设置过滤了会出现的重复项,这个具体第2个问题会说到。结果虽然一致,但是使用方式二会多判断,做无用功,所以不用方式二。在第三幅图里,我把前面初始值都改成了1,可以和第二幅图对比一下,多出了许多重复项,它们是三者顺序不一样而已。

4

2、for循环的内层循环起始值为什么是外层的起始值加1,即为什么b=a+1,c=b+1?答:前面已经展示了这样写可以过滤重复项,可能还有一些小伙伴会问到既然判断条件是用了“a*a + b*b == c*c”,为什么初始值还需要这样写。这里纠正一个误区,判断条件使用方式一并不能杜绝所有的重复情况。插一句,算法真正钻研起来还是很有趣的,我直接解释也许初学者不太能跟得上,有点晕。我先给出运行结果示例,然后再做解释。看图,代码中判断语句不变,修改了for循环初始值。(看第二、第三幅图)

5

有没有发现什么?总数跟之前的任何一次都不一样,因为出现了其它情况产生的重复项。上面我们说到修改判断条件为方式二出现了顺序不一样的重复项,这里还是出现了重复项。图里我已经圈出来了,看看这个判断条件:“a*a + b*b == c*c”,按a,b,c的顺序分别带入3,4,5和4,3,5发现都成立,对于6,8,10和8,6,10道理也是一样。从表现上来说,上面看起来是三者顺序变换的重复项,此处看起来是前两者顺序变换的重复项,后者是前者的子集。

6

说到这里可能还会有点晕,这里简单整理一下:在for循环初始值设为1(没过滤)的情况下,方式一“a*a + b*b == c*c”会出现前两者顺序不同的重复项。而方式二“a*a + b*b == c*c || a*a + c*c == b*b || b*b + c*c == a*a”包含了方式一的条件,也就是前两者顺序不同的重复项也会产生,因为还产生了其他的重复项所以看起来像是三个顺序变换产生的。说了这些,只是想说明判断条件使用方式一并不能杜绝所有的重复情况,所以上面的for循环初始值的设置是有必要的。

7

列出不重复的勾股数,必然a

注意事项

如果想弄清楚这个算法又还是没能理解就多运行几次代码,改改看结果,然后基本上就慢慢理解了。

推荐信息