初学者编程实战指南 (2)- 避免逻辑的重复

Harmonious Contest

题目描述

Given three positive integers A, B and C (0<A,B,C<=100) which denote the length of three edges, please tell me whether they can make up a legal triangle.

输入

The first line is an integer T(T<=100) which indicates the number of test cases.

Each test case consists of three integers A,B and C in a line.

输出

For each test case please output the type of triangle(Acute triangle、Right triangle or Obtuse triangle)if  A,B and C can make up a legal triangle, and output "NO" otherwise.

One line per case.

样例输入

4
3 4 4
3 4 5
3 4 6
3 4 7

样例输出

Acute triangle
Right triangle
Obtuse triangle
NO
 
下面的写法对初学if的同学来讲已经非常不错
 1  #include <stdio.h>
 2 int main(void)
 3 {
 4     int n,a,b,c;
 5     scanf("%d",&n);
 6     while(n--) {
 7         scanf("%d%d%d",&a,&b,&c);
 8         if(a+b>c&&a+c>b&&b+c>a) {
 9             if(a*a+b*b==c*c||a*a+c*c==b*b||b*b+c*c==a*a)
10                 printf("Right triangle\n");
11             else if (a*a+b*b<c*c||a*a+c*c<b*b||b*b+c*c<a*a)
12                 printf("Obtuse triangle\n");
13             else
14                 printf("Acute triangle\n");
15         } else
16             printf("NO\n");
17     }
18     return 0;
19 }

如果考虑纯粹的多分支,下面的也许略微好一点点 

 1 #include<stdio.h>
 2 int main(void)
 3 {
 4     int n, a, b, c;
 5     scanf("%d", &n);
 6     while(n--) {
 7         scanf("%d%d%d", &a, &b, &c);
 8         if(a + b <= c || a + c <= b || b + c <= a)
 9             printf("NO\n");
10         else if(a * a + b * b == c * c || a * a + c * c == b * b || b * b + c * c == a * a)
11             printf("Right triangle\n");
12         else if(a * a + b * b > c * c && a * a + c * c > b * b && b * b + c * c > a * a)
13             printf("Acute triangle\n");
14         else
15             printf("Obtuse triangle\n");
16     }
17     return 0;
18 }

 

但是上面代码的逻辑重复在于分别考虑a,b,c是最大边, 如果能求得最大边,则只需要处理一次,见下面的代码,如果能这样想,已经很不错了。

 1 #include <stdio.h>
 2 int main(void)
 3 {
 4     int a, b, c, t, n;
 5 
 6     scanf("%d", &n);
 7     while(n--) {
 8         scanf("%d%d%d", &a, &b, &c);
 9         if(a > c) {
10             t = a;
11             a = c;
12             c = t;
13         }
14         if(b > c) {
15             t = b;
16             b = c;
17             c = t;
18         }
19         if(a + b <= c)
20             printf("NO\n");
21         else if(a * a + b * b == c * c)
22             printf("Right triangle\n");
23         else if(a * a + b * b > c * c)
24             printf("Acute triangle\n");
25         else
26             printf("Obtuse triangle\n");
27     }
28     return 0;
29 }

 

但是交换的逻辑是重复的,把其提炼出来形成单独的swap函数,这是学完函数后同学能达到的最高水平。或许有同学会认为比起开始的程序这里反而复杂了。诚然,对于小的程序,重复几次可能没什么了不起,但是对于大的程序,将让程序的可读性可维护性大大下降,让代码臃肿。 

 1 #include <stdio.h>
 2 
 3 void swap(int *pa, int *pb)
 4 {
 5     int t = *pa;
 6     *pa = *pb;
 7     *pb = t;
 8 }
 9 
10 int main(void)
11 {
12     int n, a, b, c;
13     scanf("%d", &n);
14     while(n--) {
15         scanf("%d%d%d", &a, &b, &c);
16         if(a > c)
17             swap(&a, &c);
18         if(b > c)
19             swap(&b, &c);
20         if(a + b <= c)
21             printf("NO\n");
22         else if(a * a + b * b == c * c)
23             printf("Right triangle\n");
24         else if(a * a + b * b < c * c)
25             printf("Obtuse triangle\n");
26         else
27             printf("Acute triangle\n");
28     }
29     return 0;
30 }

  

"不要发明新轮子",如果存在现成的函数或代码,尽量利用它.如果我们会C++的话,有swap函数直接用,而且是引用语义,下面是代码

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 int main(void)
 6 {
 7     int n, a, b, c;
 8     scanf("%d", &n);
 9     while(n--) {
10         scanf("%d%d%d", &a, &b, &c);
11         if(a > c)
12             swap(a, c);
13         if(b > c)
14             swap(b, c);
15         if(a + b > c) {
16             if(a * a + b * b == c * c)
17                 printf("Right triangle\n");
18             else if(a * a + b * b < c * c)
19                 printf("Obtuse triangle\n");
20             else
21                 printf("Acute triangle\n");
22         } else
23             printf("NO\n");
24     }
25     return 0;
26 }

 

调用两次交换感觉还是有重复, 实际上, C++还有sort函数可以排序.见下,要注意是sort使用稍微过度了,因为我们并不需要排序,我们只是求最大的而已。

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 int main(void)
 6 {
 7     int n, a[3];
 8     scanf("%d", &n);
 9     while(n--) {
10         for(int i = 0; i < 3; i++)
11             scanf("%d", &a[i]);
12         sort(a, a + 3);
13         if(a[0] + a[1] <= a[2])
14             printf("NO\n");
15         else if(a[0] * a[0] + a[1] * a[1] == a[2] * a[2])
16             printf("Right triangle\n");
17         else if(a[0] * a[0] + a[1] * a[1] < a[2] * a[2])
18             printf("Obtuse triangle\n");
19         else
20             printf("Acute triangle\n");
21     }
22     return 0;
23 }

 

似乎已经大功告成,但是还有一个地方有重复的逻辑:

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 int main(void)
 6 {
 7     int n, a[3];
 8     scanf("%d", &n);
 9     while(n--) {
10         for(int i = 0; i < 3; i++)
11             scanf("%d", &a[i]);
12         sort(a, a + 3);
13         int diff = a[0] * a[0] + a[1] * a[1] - a[2] * a[2];
14         if(a[0] + a[1] <= a[2])
15             printf("NO\n");
16         else if(diff == 0)
17             printf("Right triangle\n");
18         else if(diff < 0)
19             printf("Obtuse triangle\n");
20         else
21             printf("Acute triangle\n");
22     }
23     return 0;
24 }

 

posted on 2014-12-02 18:35  天地过客  阅读(364)  评论(0编辑  收藏  举报

导航