zoukankan      html  css  js  c++  java
  • 一个编程小题目引发的思考(上)

    一个编程小题目引发的思考 首先简介下题目: 输入:一个不超过12位的十进制正整数 输出:打印此数字的十进制计算器表示 例: 输入:145 输出:
             __
       ||__||__
       |   | __|
    
    看到这个题目,也没多想,反正就是把这些数字打出来而已,那就一行一行打呗 于是在纸上画了几个计算器表示形式的数字: 规律是很明显的,每个数字都由3行4列组成,每一行只有固定的几种样式,比如说8的第一行是" __ ",第二行是"|__|",第三行是"|__|" 于是就有了思路:只要一位一位的读取这个数字,然后按照上中下的顺序依次打印其计算器表示的三行就行了。 由于每个数字的每一行的样式都是固定的,很容易将这些样式抽取出来,经过观察,我找出了其所有的样式,于是就有了如下的代码:
    class LCDPrinter
    {
        // all the paradigms in the LCD representation
        private static readonly string S0 = "    ";
        private static readonly string S1 = " __ ";
        private static readonly string S2 = "   |";
        private static readonly string S3 = "|   ";
        private static readonly string S4 = " __|";
        private static readonly string S5 = "|__ ";
        private static readonly string S6 = "|__|";
        private static readonly string S7 = "|  |";
        public void PrintNum(int value)
        {
            //TODO: print the number layer by layer
        }
    }
    
    接下来的问题就是依次获取一个数的每一位,通过一个递归,很容易实现这个功能:
        public void PrintNum(int value)
        {
            if (value != 0)
            {
                PrintNum(value / 10, layer);
                Console.Write(value % 10);
            }
        }
    
    测试这个方法之后,接下来的工作就是一行一行的打印数值了,按照之前的思路,我把每个数字分为上中下三层,于是可以这么写:
        public void PrintNum(int value)
        {
            PrintTopBody(value);
            Console.WriteLine();
            PrintMiddleBody(value);
            Console.WriteLine();
            PrintBottomBody(value);
            Console.WriteLine();
        }
    
    然后逐个实现每个方法,为了确保这个思路是正确的,先不用考虑所有的数字,只考虑数字1这个情况
        private void PrintTopBody(int value)
        {
            if (value != 0)
            {
                PrintTopBody(value / 10);
                int num = value % 10;
                switch (num)
                {
                    case 1:
                        Console.Write(S0);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
        }
        private void PrintMiddleBody(int value)
        {
            if (value != 0)
            {
                PrintMiddleBody(value / 10);
                int num = value % 10;
                switch (num)
                {
                    case 1:
                        Console.Write(S2);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
        }
        private void PrintBottomBody(int value)
        {
            if (value != 0)
            {
                PrintBottomBody(value / 10);
                int num = value % 10;
                switch (num)
                {
                    case 1:
                        Console.Write(S2);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
        }
    
    然后以1,11,1111作为输入进行测试,发现结果是正确的。 接下来就可以完善这三个方法了,经过一段时间的编码和测试,我完成了这道题目。其功能代码如下
        class LCDPriter
        {
            private static readonly string S0 = "    ";
            private static readonly string S1 = " __ ";
            private static readonly string S2 = "   |";
            private static readonly string S3 = "|   ";
            private static readonly string S4 = " __|";
            private static readonly string S5 = "|__ ";
            private static readonly string S6 = "|__|";
            private static readonly string S7 = "|  |";
            public void PrintNum(int value)
            {
                PrintTopBody(value);
                Console.WriteLine();
                PrintMiddleBody(value);
                Console.WriteLine();
                PrintBottomBody(value);
                Console.WriteLine();
            }
            private void PrintTopBody(int value)
            {
                if (value != 0)
                {
                    PrintTopBody(value / 10);
                    int num = value % 10;
                    switch (num)
                    {
                        case 0:
                            Console.Write(S1);
                            break;
                        case 1:
                            Console.Write(S0);
                            break;
                        case 2:
                            Console.Write(S1);
                            break;
                        case 3:
                            Console.Write(S1);
                            break;
                        case 4:
                            Console.Write(S0);
                            break;
                        case 5:
                            Console.Write(S1);
                            break;
                        case 6:
                            Console.Write(S1);
                            break;
                        case 7:
                            Console.Write(S1);
                            break;
                        case 8:
                            Console.Write(S1);
                            break;
                        case 9:
                            Console.Write(S1);
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                    }
                }
            }
            private void PrintMiddleBody(int value)
            {
                if (value != 0)
                {
                    PrintMiddleBody(value / 10);
                    int num = value % 10;
                    switch (num)
                    {
                        case 0:
                            Console.Write(S7);
                            break;
                        case 1:
                            Console.Write(S2);
                            break;
                        case 2:
                            Console.Write(S4);
                            break;
                        case 3:
                            Console.Write(S4);
                            break;
                        case 4:
                            Console.Write(S6);
                            break;
                        case 5:
                            Console.Write(S5);
                            break;
                        case 6:
                            Console.Write(S5);
                            break;
                        case 7:
                            Console.Write(S2);
                            break;
                        case 8:
                            Console.Write(S6);
                            break;
                        case 9:
                            Console.Write(S6);
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                    }
                }
            }
            private void PrintBottomBody(int value)
            {
                if (value != 0)
                {
                    PrintBottomBody(value / 10);
                    int num = value % 10;
                    switch (num)
                    {
                        case 0:
                            Console.Write(S6);
                            break;
                        case 1:
                            Console.Write(S2);
                            break;
                        case 2:
                            Console.Write(S5);
                            break;
                        case 3:
                            Console.Write(S4);
                            break;
                        case 4:
                            Console.Write(S2);
                            break;
                        case 5:
                            Console.Write(S4);
                            break;
                        case 6:
                            Console.Write(S6);
                            break;
                        case 7:
                            Console.Write(S2);
                            break;
                        case 8:
                            Console.Write(S6);
                            break;
                        case 9:
                            Console.Write(S4);
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                    }
                }
            }
        }
    
    虽然这段代码可以工作,但是怎么看怎么别扭,不知所以然的S0到S7这8个全局字符串(本身就不好命名),逻辑极其类似的PrintTopBody,PrintMiddleBody,PrintBottomBody这三个方法,使得逻辑很简单的一个程序却很难看懂。

    下篇:一个编程小题目引发的思考(下)

  • 相关阅读:
    微信用户授权,获取code
    关于swiper在vue中不生效的问题
    ES6-Set 和 Map 数据结构
    Js中caller和callee的区别
    类与对象基础总结--继承,多态
    java 类与对象基础整理
    java 的数据库操作--JDBC
    Socket的长连接和短连接
    java 的底层通信--Socket
    算法--树与递归
  • 原文地址:https://www.cnblogs.com/figure9/p/1887746.html
Copyright © 2011-2022 走看看