一个编程小题目引发的思考(上)
一个编程小题目引发的思考
看到这个题目,也没多想,反正就是把这些数字打出来而已,那就一行一行打呗
于是在纸上画了几个计算器表示形式的数字:
规律是很明显的,每个数字都由3行4列组成,每一行只有固定的几种样式,比如说8的第一行是" __ ",第二行是"|__|",第三行是"|__|"
于是就有了思路:只要一位一位的读取这个数字,然后按照上中下的顺序依次打印其计算器表示的三行就行了。
由于每个数字的每一行的样式都是固定的,很容易将这些样式抽取出来,经过观察,我找出了其所有的样式,于是就有了如下的代码:
接下来的问题就是依次获取一个数的每一位,通过一个递归,很容易实现这个功能:
测试这个方法之后,接下来的工作就是一行一行的打印数值了,按照之前的思路,我把每个数字分为上中下三层,于是可以这么写:
然后逐个实现每个方法,为了确保这个思路是正确的,先不用考虑所有的数字,只考虑数字1这个情况
然后以1,11,1111作为输入进行测试,发现结果是正确的。
接下来就可以完善这三个方法了,经过一段时间的编码和测试,我完成了这道题目。其功能代码如下
虽然这段代码可以工作,但是怎么看怎么别扭,不知所以然的S0到S7这8个全局字符串(本身就不好命名),逻辑极其类似的PrintTopBody,PrintMiddleBody,PrintBottomBody这三个方法,使得逻辑很简单的一个程序却很难看懂。
首先简介下题目:
输入:一个不超过12位的十进制正整数
输出:打印此数字的十进制计算器表示
例:
输入:145
输出:
1 2 3 | __ ||__||__ | | __| |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 } } |
1 2 3 4 5 6 7 8 | public void PrintNum( int value) { if (value != 0) { PrintNum(value / 10, layer); Console.Write(value % 10); } } |
1 2 3 4 5 6 7 8 9 | public void PrintNum( int value) { PrintTopBody(value); Console.WriteLine(); PrintMiddleBody(value); Console.WriteLine(); PrintBottomBody(value); Console.WriteLine(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | 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(); } } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述