您的位置:首页 > 职场人生

黑马程序员-7k面试题之交通灯管理系统

2014-05-18 21:03 375 查看
----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

面试题要求:

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

例如:

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

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

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

。。。。。

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

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

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

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

5.每辆车通过路口时间为1秒(可通过sleep的方法模拟)

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

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

编程思想:

用S,N,E,W分别表示南,北,东,西方向,S2N代表由南往北的信号灯,余下依次类推。来考虑一个完整的信号灯循环:

1.S2N亮,由南向而来去往北向的直行车辆通行,同时四个方向的右转车辆通行。

2.接着S2W亮,S2N灭,由南向而来去往西向的左转车辆通行,同时四个方向的右转车辆通行。

3.接着E2W亮,S2W灭,由西向而来去往东向的直行车辆通行,同时四个方向的右转车辆通行。

4.接着E2S亮,E2W灭,由西向而来去往北向的左转车辆通行,同时四个方向的右转车辆通行。

。。。。。。

我们发现S2N-N2S,S2W-N2E,E2W-W2E,E2S-W2N是一一对应的,另外四个控制因为是控制右转车辆的,不考虑。

因此只需控制S2N,S2W,E2W,E2S四个灯的亮灭即可。

//产生车辆的工厂,每辆车都对应有一个唯一的车牌号

<span style="font-family:KaiTi_GB2312;font-size:18px;">public class vechiclesCenter
{
private static int lastNumber = 0;
private static vechiclesCenter instance = new vechiclesCenter();

public static  vechiclesCenter getCarCenter()
{
return instance;
}

public int incCar()
{
return (++lastNumber);
}
}</span>


//定义一个枚举,用于表示12个灯的状态

<span style="font-family:KaiTi_GB2312;font-size:18px;">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 opposition,next; //对面灯和下一个灯的枚举对象名字
private boolean lighted;	//表示灯的亮灭状态

private Lamp(String oppsotion,String next,boolean lighted)  //构造函数,每个对象都对应有对面灯,下一个灯和灯的状态
{
this.opposition = oppsotion;
this.next = next;
this.lighted = lighted;
}

//得到灯的状态
public boolean isLighted()
{
return lighted;
}

//将当前灯便绿
public void light()
{
this.lighted = true; 	//将当前灯的lighted 置为true
if(this.opposition != null)	//判断opposition变量是否为null,否则会陷入死循环
{
Lamp.valueOf(opposition).light();
}
System.out.println(name() +" 绿了,现在有6个方向上的车正在通行!!");
}

//将当前变红,同时将下一个灯变绿
public Lamp blackOut()
{
this.lighted = false; //将当前灯的lighted 置为false
if(this.opposition != null)
{
Lamp.valueOf(this.opposition).blackOut();
}

Lamp nextTmpString = null;
if(this.next != null)
{
nextTmpString = Lamp.valueOf(this.next);  //得到下一个灯的枚举对象
System.out.println("绿灯方向转向了 "+ this.next);
nextTmpString.light();			//将下一个灯变绿
}

return nextTmpString;
}
}</span>


//该类根据为每个方向上的道路创建两个线程,第一个线程按随机间隔时间添加往这个方向上通行的车辆,第二个线程按照1s时间间隔判断这个方向上的交通灯状态。并且创建一个存放该通行该路线的车辆的容器

<span style="font-family:KaiTi_GB2312;font-size:18px;">public class Road
{
private List<String> carList = new ArrayList<String>(); //存放车辆的容器
private String name = null;                //该路线对应的方向名称
Road(String name)
{
this.name  = name;
Executors.newSingleThreadExecutor().execute(new Runnable()   //该线程负责不断往容器中添加车辆
{
public void run()
{
while(true)
{
try
{
Thread.sleep((new Random().nextInt(10)+1)*1000);  //添加车辆前睡眠一个随机时间,模拟不断到来的随机车辆
carList.add(Road.this.name+" 方向上的"+vechiclesCenter.getCarCenter().incCar()+"车"); //往容器中添加车辆
}
catch (Exception e)
{
e.printStackTrace();
}
}

}
});

Executors.newScheduledThreadPool(1).scheduleAtFixedRate(    //该线程每隔一秒时间检查该线路的灯的情况。
new Runnable()
{

public void run()
{
if(carList.size() > 0)  //如果该方向上有车辆要通行
{
if(Lamp.valueOf(Road.this.name).isLighted())  //如果该方向上的灯是绿的
{
System.out.println(carList.remove(0)+" 正在通行");  //从容器中取出一辆车模拟该车在该路线上通行
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}</span>


//该类控制交通灯的状态进行循环,先将S2N变绿,创建一个线程每隔10秒点亮当前灯的下一个灯

<span style="font-family:KaiTi_GB2312;font-size:18px;">public class LampCtroller
{
private Lamp currentLamp;
public LampCtroller()
{
currentLamp = Lamp.S2N;
currentLamp.light();
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable()
{

public void run()
{
System.out.println("come on!!!");
currentLamp.blackOut();   //将灭掉当前灯,并点亮下一个灯
}
},
10,
10,
TimeUnit.SECONDS);
}
}</span>


//测试

<span style="font-family:KaiTi_GB2312;font-size:18px;">public class MainClass
{
public static void main(String[] args)
{
String[] roadsStrings = {"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"}; //12个等对应的枚举对象的名字
for(int i=0; i<roadsStrings.length; i++)
new Road(roadsStrings[i]);         //根据灯名,分别启动一个线程往相应的方向上增加车辆
new LampCtroller();			   //启动一个线程控制灯的状态
}

}</span>


程序运行部分结果:

N2S 绿了,现在有6个方向上的车正在通行!!

S2N 绿了,现在有6个方向上的车正在通行!!

W2S 方向上的4 号车 正在通行

S2E 方向上的7 号车 正在通行

N2S 方向上的6 号车 正在通行

E2N 方向上的10 号车 正在通行

N2W 方向上的8 号车 正在通行

S2N 方向上的11 号车 正在通行

N2S 方向上的9 号车 正在通行

N2W 方向上的17 号车 正在通行

come on!!!

绿灯方向转向了 S2W

N2E 绿了,现在有6个方向上的车正在通行!!

S2W 绿了,现在有6个方向上的车正在通行!!

S2W 方向上的3 号车 正在通行

N2E 方向上的2 号车 正在通行

N2E 方向上的16 号车 正在通行

S2W 方向上的21 号车 正在通行

N2E 方向上的20 号车 正在通行

W2S 方向上的22 号车 正在通行

N2W 方向上的24 号车 正在通行

S2E 方向上的27 号车 正在通行

E2N 方向上的29 号车 正在通行

W2S 方向上的28 号车 正在通行

S2E 方向上的32 号车 正在通行

S2W 方向上的33 号车 正在通行

W2S 方向上的36 号车 正在通行

N2E 方向上的37 号车 正在通行

come on!!!

绿灯方向转向了 S2W

N2E 绿了,现在有6个方向上的车正在通行!!

S2W 绿了,现在有6个方向上的车正在通行!!

S2E 方向上的47 号车 正在通行

E2N 方向上的43 号车 正在通行

N2W 方向上的45 号车 正在通行

W2S 方向上的44 号车 正在通行

S2W 方向上的46 号车 正在通行

N2W 方向上的48 号车 正在通行

N2W 方向上的49 号车 正在通行

............................

----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: