`

告诉你什么是优雅的代码(5)------ 百度之星也是普通人(答案)

    博客分类:
  • Java
阅读更多

最近在写优雅代码系列的时候,由于程序偏向算法性,代码写得比较PO。于是今天打算用OO来写火柴游戏。谁知道,一旦打开我那OO思想的闸门,就让我意识到什么是厚积薄发,各种设计模式便如一个个性感的美女一样浮现在我脑海中,令我欲罢不能。于是一个个的类便如雪片一般飘散开来。写到兴起,竟抛弃了火柴游戏的实现,写成了一个“多位数运算控制台显示系统”的怪胎。首先来看下这个系统的使用方法:

public static void main(String[] args) {

        MultiDigit num1 = new MultiDigit(42723);

        MultiDigit num2 = new MultiDigit(2577);

        Operation op = OperFactory.getOper('+');

        Expression exp = new Expression(num1,num2,op);

        exp.draw();

       

    }
 



执行后,运行结果如下:

 M  M MMMM MMMM MMMM MMMM        MMMM MMMM MMMM MMMM        M  M MMMM MMMM MMMM MMMM
 M  M    M    M    M    M   |       M M       M    M  ---   M  M M       M M  M M  M
 MMMM MMMM    M MMMM MMMM  -+-   MMMM MMMM    M    M        MMMM MMMM MMMM M  M M  M
    M M       M M       M   |    M       M    M    M  ---      M    M    M M  M M  M
    M MMMM    M MMMM MMMM        MMMM MMMM    M    M           M MMMM MMMM MMMM MMMM

 

 


且不论这里显示效果不是太好,来说一下这个系统的设计。整个系统大概用到了“单例模式”,“模板模式”,“享元模式”,“工厂模式”,大概20个类,有极佳的可扩展性。不是太难,就不拿出来了。



好了,有了以上这个超强的显示系统。再来分析一下火柴游戏的算法。首先来看一下这张表:


数字   加一   减一   自移动

0       8                     6,9

1

2                              3

3       9                     2

.

.

.

9       8       5,3        6,0


这张是反映火柴可能变化的表,加一表示增加一根火柴,我们将每个数字的变化存到集合dic[],当检验某个表达式时,遍历一下三个数的dic[],如果符合移动规则并且等式成立,则找到了可行解。合理的移动规则有三种:1.没有产生过移动 2.一加一减 3.自移动一次,如何表示和计算这种规则是个难点。我的方法如下,为每个数字附加一个值,见下表:


数字 (0) 加一 (1) 减一 (3) 自移动 (4)


对应三条规则,对于任意三个数字,附加值的计算结果分别为:

0+0+0 = 0

0+1+3 = 4

0+0+4 = 4

可见,sum(3个数) == 0 或4 ,则是符合移动规则的。

于是,一个优雅的方案浮出水面:

 

import java.util.ArrayList;
import java.util.List;

import app.matchgame.digit.Expression;
import app.matchgame.digit.MultiDigit;
import app.matchgame.digit.OperFactory;
import app.matchgame.digit.Operation;


class Node{
	int digit;
	int flag;
	public Node(int digit,int flag){
		this.digit = digit;
		this.flag = flag;
	}
}
class Digit{
	
	List<Node> dic = new ArrayList<Node>();
	
	int p = 0;
	public void addNode(Node node){
		dic.add(node);
	}
	public boolean hasNext(){
		return p < dic.size();
	}
	public Node next(){
		return dic.get(p++);
	}
	public void clear(){
		p = 0;
	}
	public Digit clone(){
		Digit clone = new Digit();
		clone.dic = this.dic;
		clone.p = 0;
		return clone;
	}
}
public class MatchGame {
	private Digit[] digTable;
	public void init(){
		digTable = new Digit[10];
		for (int i = 0; i < digTable.length; i++) {
			digTable[i] = new Digit();
			digTable[i].addNode(new Node(i,0));
			
		}
		digTable[0].addNode(new Node(8,1));
		digTable[0].addNode(new Node(6,4));
		digTable[0].addNode(new Node(9,4));
		
		digTable[2].addNode(new Node(3,4));
		
		digTable[3].addNode(new Node(9,1));
		digTable[3].addNode(new Node(2,4));
		
		digTable[5].addNode(new Node(6,1));
		digTable[5].addNode(new Node(9,1));
		digTable[5].addNode(new Node(3,4));
		
		digTable[6].addNode(new Node(8,1));
		digTable[6].addNode(new Node(5,3));
		digTable[6].addNode(new Node(0,4));
		digTable[6].addNode(new Node(9,4));
		
		digTable[7].addNode(new Node(1,3));
		digTable[8].addNode(new Node(6,3));
		digTable[8].addNode(new Node(9,3));
		
		digTable[9].addNode(new Node(8,1));
		digTable[9].addNode(new Node(5,3));
		digTable[9].addNode(new Node(3,3));
		digTable[9].addNode(new Node(0,4));
		digTable[9].addNode(new Node(6,4));
	}
	
	public void calc(int a,int b,int c, Operation op){
		Digit dig1 = digTable[a].clone();
		Digit dig2 = digTable[b].clone();
		Digit dig3 = digTable[c].clone();
		while(dig1.hasNext()){
			Node d1 = dig1.next();
			dig2.clear();
			while(dig2.hasNext()){
				Node d2 = dig2.next();
				dig3.clear();
				while(dig3.hasNext()){
					Node d3 = dig3.next();
					int tmp = d1.flag + d2.flag + d3.flag;
					if((tmp == 0 || tmp == 4)&&
							op.oper(d1.digit,d2.digit) == d3.digit){
						
						MultiDigit num1 = new MultiDigit(d1.digit);
						MultiDigit num2 = new MultiDigit(d2.digit);
						Expression exp = new Expression(num1,num2,op);
						exp.draw();
						System.out.println();
					}
					
				}
			}
		}
	}
	
	public static void main(String[] args) {
		MatchGame demo = new MatchGame();
		demo.init();
		//此处可根据输入获取相应运算
		Operation op = OperFactory.getOper('+');		
		demo.calc(3, 6, 9,op);
	}

}

 

运行结果如下:

 

 

 HHHH        HHHH        HHHH
    H   |    H     ---   H  H
 HHHH  -+-   HHHH        HHHH
    H   |    H  H  ---      H
 HHHH        HHHH        HHHH

 HHHH        HHHH        HHHH
    H   |    H     ---   H  H
 HHHH  -+-   HHHH        HHHH
    H   |       H  ---   H  H
 HHHH        HHHH        HHHH
 

 

0
0
分享到:
评论
2 楼 Shengli_fu 2015-06-24  
1 楼 mengsina 2011-10-26  
高手啊,膜拜了。

相关推荐

    vue-baidu-map离线百度地图,并附带jar包免费下载百度瓦片数据

    1.vue-baidu-map在线地图...4.2022-12-05日更新,可能会出现项目实际部署之后,地图无法拖拽的问题,新添加了8个js文件,并修改了一下baidu-api.js代码引入这八个js(直接搜索http://127.0.0.1/js换成你本地路径就行)

    华中科技大学-计算机组成原理-educoder Logisim-自己动手画cpu-答案代码

    华中科技大学-计算机组成原理-educoder Logisim-自己动手画cpu-答案代码 1.8位可控加减法电路设计 2.CLA182四位先行进位电路设计 3.4位快速加法器设计 4.16位快速加法器设计 5.32位快速加法器设计 6.5位无符号...

    257-普通定时器时钟(51单片机C语言实例Proteus仿真和代码)

    257-普通定时器时钟(51单片机C语言实例Proteus仿真和代码)257-普通定时器时钟(51单片机C语言实例Proteus仿真和代码)257-普通定时器时钟(51单片机C语言实例Proteus仿真和代码)257-普通定时器时钟(51单片机C语言实例...

    Qt5-嵌入百度地图demo

    在本文中,我们将深入探讨如何使用Qt5框架与WebEngineView组件来嵌入百度地图,以便在您的应用程序中集成地理定位功能。这个示例项目,"Qt5-嵌入百度地图demo",演示了如何利用Qt5.5的特性与百度地图API进行交互,...

    GARCH-MIDAS、DDC-MIDAS模型MATLAB代码

    标题中的"GARCH-MIDAS、DDC-MIDAS模型MATLAB代码"指的是在金融计量领域中,使用MATLAB编程实现的两种重要的模型:GARCH-MIDAS(Generalized Autoregressive Conditional Heteroskedasticity with Mixed Data ...

    中国河流代码SL249- 012

    水利行业标准 本标准是水利技术标准体系中的水利信息化标准之一,是水利行业信息系统中河流代码编制的基本规定.根据水利部水利行业标准制修订计划,按照《标准化工作导则第1部分:标准的结构和编写》(GB/T 1.1—...

    2023年最新全国各省五级行政区划代码-mysql表数据

    依国家统计局2023年度全国统计用区划代码和城乡划分代码(更新维护的标准时点为2023年09月11日)生成的MySQL数据(字段包含:行政区划代码,行政区划,行政区划-全称,行政区划代码-省,行政区划-省,行政区划代码-市,...

    ucos-ii全部源代码

    ucos-ii全部源代码 ucos-ii全部源代码 ucos-ii全部源代码ucos-ii全部源代码ucos-ii全部源代码ucos-ii全部源代码 ucos-ii全部源代码ucos-ii全部源代码ucos-ii全部源代码ucos-ii全部源代码

    C#范例开发大全源代码--刘丽霞版

    《C#范例开发大全源代码--刘丽霞版》是一部深入浅出的C#编程实践教程,由知名IT教育专家刘丽霞编著。该资料集包含了丰富的C#编程实例,旨在帮助开发者掌握C#语言的核心概念、特性和应用技巧。通过这份源代码,学习者...

    141-定时做普通时钟可调(51单片机C语言实例Proteus仿真和代码)

    141-定时做普通时钟可调(51单片机C语言实例Proteus仿真和代码)141-定时做普通时钟可调(51单片机C语言实例Proteus仿真和代码)141-定时做普通时钟可调(51单片机C语言实例Proteus仿真和代码)141-定时做普通时钟可调(51...

    TVP-VAR模型的MATLAB代码

    5. 文档阅读:如果代码附带了说明文档,务必仔细阅读以理解代码的用途和用法。 通过理解和应用这个TVP-VAR模型的MATLAB代码,研究者可以深入探索经济系统的动态性质,为政策制定和市场预测提供有力的分析工具。

    fisheye-代码评审-详细培训教程

    ### Fisheye-代码评审-详细培训教程 #### 一、Fisheye的核心功能概览 **1. 监控(Keep Tabs)** - **个人与团队追踪:** FishEye提供了一种全面的方式让您能够跟踪个人或整个团队的源代码变更。这包括您自己、您...

    编译原理课后答案---WORD版

    5. **优化(Optimization)**:对生成的代码进行改进,提高运行效率,如删除冗余计算、死代码消除、循环展开等。 在课后答案中,可能涉及的具体知识点包括: - **正则表达式和有限状态自动机**:词法分析的基础,...

    典型的多目标优化算法matlab代码---PlatEMO(你所需要多目标优化代码都有)

    在多目标优化领域,Matlab是一种常用的编程工具,因为它提供了丰富的数学函数库和直观的编程环境,...如果你是这个领域的研究者或学生,通过学习和使用PlatEMO,你可以更深入地理解和掌握多目标优化算法的原理和应用。

    C语言PTA-数组答案代码合集(湖工1-50)

    C语言PTA-数组答案代码合集(湖工1-50)

    TortoiseSVN-1.14.5.29465-x64-svn-1.14.2.rar

    《TortoiseSVN-1.14.5.29465-x64-svn-1.14.2.rar:一个强大的版本控制系统工具》 TortoiseSVN,这个名字可能对许多...如果你是一名开发者,那么掌握TortoiseSVN的使用方法,无疑将提升你的开发效率和代码管理水平。

    2021csp-j初赛试题及答案.docx

    总的来说,2021年CSP-J初赛试题及答案对于参赛者来说是宝贵的复习资源,通过分析和解答这些题目,考生可以巩固编程基础,提升算法能力,为后续的比赛做好充分准备。同时,考生应注重平时的积累,不断挑战自我,以...

    L-BFGS的MATLAB代码

    5. 约束处理:如果存在约束条件,需要在此步骤中进行处理。 6. 线性搜索:找到一个合适的步长,使得沿着下降方向移动后,目标函数的减小量最大。 7. 参数更新:根据找到的步长,更新参数。 8. 检查收敛:比较当前和...

    计算ADS-B经纬度的CPR算法源代码

    标题中的"计算ADS-B经纬度的CPR算法源代码"是指使用特定的算法来解析ADS-B(Automatic Dependent Surveillance-Broadcast)数据,从而确定航空器的经度和纬度坐标。ADS-B是一种自动的航空监视技术,允许飞机广播其...

    MQ-2烟雾传感器51单片机代码

    这款传感器能够检测多种可燃气体,如甲烷、丙烷、氢气,同时也能对烟雾进行探测。51单片机是经典且广泛应用的微控制器,其结构简单,易于编程,适合初学者和专业人士进行各种嵌入式项目开发。 在这个项目中,51...

Global site tag (gtag.js) - Google Analytics