• 初学者编程实战指南 (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 }
  • 相关阅读:
    pyqt5 树节点点击实现多窗口切换
    pyglet self.
    itchat key
    python队列Queue
    Python建立多线程任务并获取每个线程返回值
    利用Python实现多线程聊天功能
    Python3.5+PyQt5多线程+itchat实现微信防撤回桌面版代码
    pyglet player sound
    文件打开的几种访问模式
    pyglet StaticSource
  • 原文地址:https://www.cnblogs.com/4bytes/p/4137878.html
Copyright © 2020-2023  润新知