新手学 C 语言求最大公约数的时候,是不是忽略了负数的情况?比如输入 - 12 和 18,本来应该得到 6,可自己写的代码算出个 - 6,或者干脆是其他数字,这时候就懵了,不知道问题出在哪。其实啊,处理负数是求最大公约数里很容易踩的坑,今天兔子哥就专门讲讲这个事儿,告诉你负数到底该怎么处理,代码该怎么改,保证看完就明白,一起往下看吧!
为啥负数会让结果出错?先看个例子
咱们先看一段代码,这是没处理负数的情况:
c运行
#include int gcd(int a, int b) {int temp;while (b != 0) {temp = a % b;a = b;b = temp;}return a;}int main() {printf("%d\n", gcd(-12, 18)); // 猜猜输出啥?return 0;}你觉得这段代码会输出 6 吗?其实不会,它输出的是 6 吗?不对,实际运行一下就知道,结果是 6?哎,等一下,我之前记混了,有时候可能对,有时候可能错。比如换成 gcd (-18, 12),结果又不一样了。这是因为 C 语言里负数取余的结果符号,是跟着被除数走的,比如 - 12 % 18 结果是 - 12,12 % -18 结果是 12,这样辗转相除下去,最后得到的结果符号就可能不对。
所以啊,负数不处理的话,结果可能对可能错,全看输入的数谁正谁负,这可不是咱们想要的,最大公约数哪有负数的说法呢。
最简单的办法:先把负数转成正数
既然负数会捣乱,那咱们在计算之前,先把两个数都变成正数不就行了?对,就是这么简单。用绝对值函数或者一个简单的判断都行。
改一下代码试试:
c运行
#include int gcd(int a, int b) {int temp;// 把负数转成正数if (a < 0) a = -a;if (b < 0) b = -b;// 剩下的和原来一样while (b != 0) {temp = a % b;a = b;b = temp;}return a;}int main() {printf("%d\n", gcd(-12, 18)); // 这次输出6,对了printf("%d\n", gcd(-18, -12)); // 输出6,也对了return 0;}你看,就加了两句判断,如果 a 是负数就变成它的相反数,b 也是一样。这样不管输入的是正数还是负数,都会当成正数来算,结果自然就是正的最大公约数了。这方法简单吧,新手一学就会。
用绝对值函数 abs (),更简洁
除了自己写判断,C 语言里还有个现成的函数叫 abs (),在 stdlib.h 头文件里,专门用来求整数的绝对值。用它来处理负数,代码会更简洁。
代码可以改成这样:
c运行
#include #include // 要用abs()得包含这个头文件int gcd(int a, int b) {int temp;// 用abs()转成正数a = abs(a);b = abs(b);while (b != 0) {temp = a % b;a = b;b = temp;}return a;}这样写是不是更干净?不过要记住,用 abs () 必须加
#include ,不然编译会报错,说 abs 没定义。之前有个同学就忘了加这个头文件,改了半天都不知道错在哪,这点可得注意。不同处理方式对比表,一目了然
| 处理方式 | 代码示例 | 优点 | 注意事项 |
|---|---|---|---|
| 不处理负数 | 直接计算 | 代码短 | 结果可能为负数或错误 |
| 手动判断转正数 | if(a<0)a=-a; | 不用额外头文件 | 要写两行判断 |
| 用 abs () 函数 | a=abs(a); | 代码简洁 | 必须包含 stdlib.h |
从表上能看出来,最好用的还是后两种方法。手动判断虽然多写两行,但不用记头文件;abs () 函数更简洁,但得记得包含头文件。新手可以根据自己的情况选,反正目的都是把负数转成正数。
自问自答:为啥最大公约数不能是负数?
可能有人会问,公约数为啥不能是负数呢?比如 - 6 也是 - 12 和 18 的公约数啊。但咱们平时说的最大公约数,一般都是指正的那个,这是数学上的习惯。就像说 “几个数的最大公约数是几”,没人会说负数,所以代码里把结果处理成正数,才符合大家的习惯。
那如果题目里明确说要考虑负数呢?这种情况很少见,但真遇到了,你可以在返回结果的时候加个判断,比如根据输入数的符号来决定结果的符号。不过这种需求太少了,新手先掌握把结果转成正数的方法就行。
兔子哥刚开始学的时候,也没注意负数的问题,作业里有道题输入是负数,结果算错了,老师圈出来才知道。后来才明白,写代码不能只考虑正数,得把各种情况都想到。其实处理负数的办法很简单,就是先转成正数再计算,关键是要有这个意识。
所以啊,以后写求最大公约数的代码,不管题目里说没说有负数,最好都加上处理负数的步骤,这样代码才更完善,不容易出错。多试几个负数的例子,比如输入 - 24 和 - 36,看看结果对不对,练几次就熟练了。希望这些能帮到你,下次碰到负数也不用怕了!
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~