【黑马程序员】7k面试题之交通灯

------- Windows Phone 7手机开发.Net培训、期待与您交流! -------

 交通灯项目需求:

模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:

 

        异步随机生成按照各个路线行驶的车辆。

例如:

       由南向而来去往北向的车辆 ---- 直行车辆

       由西向而来去往南向的车辆 ---- 右转车辆

       由东向而来去往南向的车辆 ---- 左转车辆

       。。。

 

       信号灯忽略黄灯,只考虑红灯和绿灯。

 

       应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。

      具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。

注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。

 

        每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。

 

        随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。

 

       不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。

交通灯项目需求分析思路:

项目为模拟现实生活中的交通信号灯,为方便业务逻辑分析我们先来画图分析。

项目分为三大主体:路,交通灯,车。

上图所示,根据需求我们得知一共有12条路线。南---->北,北.---->南,南---->西,北---->东,东---->西,西---->东,东---->南,西---->北,南---->东,北---->西,东---->北,西---->南。

每条路有自己的车,车为路的数据,所以根据面向对象设计模式 ,设计Road类,封装road类。 

Road类应该具有的方法和属性。

name:路的方向。

vechicles:存储车辆的集合。

public Road(String name):

构造方法,在创建路对象的时候,因该给路一个名字,然后用这个名字的信号灯来控制此的可行与否。

应该不断有车上路并排队过信号灯,所以创建Road对象时,应该加一个线程,每过若干时间为这条路上增加一辆车。

定时器:路应该每过1秒来判断一下此路是否可通行(是否为绿灯),然后让车队里的每一辆车从第一辆开始过路口。

package com.isoftstone.interview.traffic;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Road {
	private List<String> vechicles = new ArrayList<String>();//车辆集合
	private String name=null;//名字方向。
	public Road(){
		//无参构造方法
	}
	public Road(String name){
		this.name=name;//路的方向
		ExecutorService pool= Executors.newSingleThreadExecutor();
		pool.execute(
			new Runnable(){
				public void run(){
					for(int i=0;i<1000;i++){
						try {
							Thread.sleep((new Random().nextInt(10)+1)*1000);//随机(1-10)秒后给本路添加一辆汽车
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						vechicles.add(Road.this.name+"_"+i);//随机(1-10)秒后给本路添加一辆汽车

						
						
					}
				}
			}
		
		);
		
		ScheduledExecutorService timer= Executors.newScheduledThreadPool(1);
		timer.scheduleWithFixedDelay(new Runnable(){
			public void run(){
				if(vechicles.size()>0){
					boolean lighted=Lamp.valueOf(Road.this.name).isLighted();//得到当前路灯的可行状态
					//如果可行,则每秒过一辆车
					if(lighted){

						System.out.println(vechicles.remove(0)+"is traversing!");
					}
				}
			}
			
		}, 1, 1, TimeUnit.SECONDS);
		
	}
}

上图所示,根据需求我们得知一共有12条路线。南---->北(S2N),北.---->南(N2S),南---->西(S2W),北---->东(N2E),东---->西(E2W),西---->东(W2E),东---->南(E2S),西---->北(W2N),南---->东(S2E),北---->西(N2W),东---->北(E2N),西---->南(W2S)。

12条路线因该由12个信号灯来指挥当前哪条线路可行驶。

信号灯应该具备的属性:

相对的灯:opposite;//相对的灯的可行状态始终和this一样。例:南往北为绿灯,北往南也为绿灯。

接下来变绿的灯;next;

当前灯可行状态:lighted;

方法:

构造方法:Lamp(String opposite,String next ,boolean lighted);//为灯设置属性。

得到灯的可行状态:isLighted();

设置等的可行状态为true:light();

变灯(把当前所有绿灯关闭,开启接下来路线绿灯):blackOut();

需求“:

右转车辆不受信号灯控制

车辆行驶顺序,假如南北先为绿灯:

1. 南---->北   北.---->南

10秒后,南北绿灯变为红灯,南---->北   北.---->南不可行。换为左拐:

2. 南---->西   北.---->

10秒后,南西左拐绿灯变为红灯,南---->西   北.---->东不可行。换为东西直行

3. 东---->西   西---->东

10秒后,东西绿灯变为红灯东---->西   西---->东不可行。换为东西左拐:

4.东---->南   西---->

10秒后。。。第四步跳回第一步,依次循环变灯。



了解需求后,我们来写这个类,因为这12个灯为固定不变,所以这里我用枚举。

package com.isoftstone.interview.traffic;

public enum Lamp {
	S2N("N2S","S2W",false),//设置属性
	S2W("N2E","E2W",false),
	E2W("W2E","E2S",false),
	E2S("W2N","S2N",false),
	N2S(null,null,false),//接下来四个灯为上面四个的对面灯,通过上面四个灯已经设置好属性“对面灯”和下一个绿灯的属性,所以接下来四个不用设置。
	N2E(null,null,false),
	W2E(null,null,false),
	W2N(null,null,false),
	S2E(null,null,true),//下面四个为左拐,一直通行不做控制。
	E2N(null,null,true),
	N2W(null,null,true),
	W2S(null,null,true);
	
	private String opposite;//当前绿灯的方向
	private String next;//下一个绿灯的方向
	private boolean lighted;//
	private Lamp(){};
	private Lamp(String opposite,String next ,boolean lighted){
		this.opposite=opposite;
		this.next=next;
		this.lighted=lighted;
		
	}
	//得到当前灯是否可行。
	public boolean isLighted(){
		return lighted;
		
	}
	//把当前灯和当前灯的对面灯设置为绿灯可行。
	public void light(){
		this.lighted=true;
		if (opposite!=null){
			Lamp.valueOf(opposite).light();
		}
		
	}
	//把当前灯和当前灯对面的灯设置为红灯,并把接下来应该转为绿灯的灯和他的对面灯转为绿灯。
	public Lamp blackOut(){
		this.lighted=false;
		if (opposite!=null){
			Lamp.valueOf(opposite).blackOut();
		}
		
		//Lamp nextLamp=Lamp.valueOf(next);
		
		Lamp nextLamp = null;
		if (next!=null){
			//nextLamp=Lamp.valueOf(next);
			Lamp.valueOf(next).light();
			System.out.println("绿灯从"+name()+"------------>切换为"+next);
		}
		return nextLamp;
	}
	
}

写到这里灯的设计和代码都写出来,这里还差一个控制灯的一个控制器,让灯每过10秒按照需求变化。

package com.isoftstone.interview.traffic;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class LampController {
	private Lamp currentLamp;
	public LampController(){
		currentLamp=Lamp.S2N;
		currentLamp.light();
		ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(
				new Runnable(){
					public void run(){
						System.out.println(currentLamp.name());
						currentLamp=currentLamp.blackOut();
						
						if(currentLamp==null){
							System.out.println("null");
						}
					}
				}
				
				
				, 
				10, 
				10, 
				TimeUnit.SECONDS
		);
	}
}
最后一步:创建一个灯控制器和12个方向的路,路会自动增加车辆,灯会每个一段时间自动变换。绿灯的路会让车辆一辆一辆通过。

package com.isoftstone.interview.traffic;

class MainClass {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Lamp nextLamp=Lamp.valueOf("dfdfdf");
		// TODO Auto-generated method stub
		String [] directions=new String[]{
				"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","E2W","W2S"
		};
		for(int i = 0 ;i<directions.length;i++){
			new Road(directions[i]);
		}
		
		new LampController();
	}

}

项目感言

交通灯在现实生活中是一个实实在在的项目,虽然我们现在写的这个小程序只是实现了一些个简单的逻辑,但是这个小项目他培养的是编程设计的思维,拿到一个项目首先得会分析需求,然后实现需求。写程序之前学好基础固然重要,但是也一定得会设计程序。一个好的程序员必须要有好的基础和好的思维。这个小项目如果写得出来,我相信我将来可以实现更复杂的逻辑。非常感谢张老师!

------- Windows Phone 7手机开发.Net培训、期待与您交流! -------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值