———–android培训、java培训、java学习型技术博客、期待与您交流!————
1
7K面试题:交通灯管理系统的模拟
题目要求:
模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:
异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 —- 直行车辆
由西向而来去往南向的车辆 —- 右转车辆
由东向而来去往南向的车辆 —- 左转车辆
。。。
信号灯忽略黄灯,只考虑红灯和绿灯。
应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
具体分析:
首先应该分析,在这个十字路口应该有十二条不同的线路(就是车的走向),向右拐的线路可以一直是绿灯,可以不考虑。这样就剩下八条线路,(直行和向左拐的线路)。有知道,对向的线路应该是对称的,所以可以只考虑四条线路(对向的线路对称)。
灯对象的设计:有十二个方向的路线,就应该有十二个灯来控制,十二个灯可以用枚举类来做。只要有四个灯有逻辑(第一个逻辑:该等本身为绿灯的时候,对应方向的灯也该是绿的,第二个逻辑:该等本身变红后,应该让下一个灯变绿)。
灯的控制系统对象:随机的产生,让不同方向上的灯交替进行变换,要有让灯变绿的方法,和让灯变红的方法。
把路看成一个集合,把车看成集合中的元素。(车通过十字路口的效果是,集合中元素的增删)
Road(类)
package Traffic_system;
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
{
String name;
List vechicles=new ArrayList();
public Road( String name)
{
this.name=name;
//自动开启一个线程,每隔十秒钟向集合中添加一辆车
//产生一个线程池,
ExecutorService pool=Executors.newSingleThreadExecutor();
pool.execute(new Runnable()
{
@Override
public void run()
{
for (int i = 0; i <1000; i++)
{
try
{
Thread.sleep((new Random().nextInt(11))*1000);//休息1——10秒之后,增加一辆车
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
vechicles.add(Road.this.name+"--"+i);
}
}
});//这是增加车
//下面要怎么让车通过:通过一个定时器。检查对应路上的灯是否为绿,是就减少车辆(还要看这辆前边是否有车,没车才能通过)
ScheduledExecutorService timer= Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable()
{
@Override
public void run()
{
if(vechicles.size()>0)
{
boolean lamp=Lamp.valueOf(Road.this.name).islightde();//路要检查自己该路线上的灯的状态
if(lamp)
{
System.out.println(vechicles.remove(0)+"--车通过路口!");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
灯类
package Traffic_system;
import com.itheima.reText;
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 boolean lighted;
private String oppsite;//对应方向的灯,应该是Lamp类型,可是为何是String类型,是因为在构造第一个对象的时候,要使用后边还没有的对象,
private String next;//所以用String类型,当以后要用到此对象是,可通过valueof()方法,把对应的String类型对象,转换成枚举实例
private Lamp(String oppsite,String next,boolean lighted)
{
this.oppsite=oppsite;
this.next=next;
this.lighted=lighted;
}
private Lamp()
{}
public boolean islightde()//判断是否是绿灯
{
return lighted;
}
public void light()//让灯变绿,此时要看此灯有没有对应的灯,有,就把对应的灯变绿
{
this.lighted=true;
if(oppsite!=null)
{//此时要用到对应的灯,可此时oppsite确实String类型,就需要把String类型,变成枚举实例对象
Lamp.valueOf(oppsite).light();
}
System.out.println(name()+"此方向上的灯的绿的,应该有6条可以通行的线路");
}
public Lamp unlight()//让灯变红,此灯变红后就要让对应的灯变绿,还要让下一个灯变绿
{
this.lighted=false;
if(oppsite!=null)//此灯变红后就要让对应的灯变红
{//此时要用到对应的灯,可此时oppsite确实String类型,就需要把String类型,变成枚举实例对象
Lamp.valueOf(oppsite).unlight();
}
Lamp nextLamp=null;
if(next!=null)//还要让此灯的下一个灯变绿
{//此时要用到对应的灯,可此时oppsite确实String类型,就需要把String类型,变成枚举实例对象
nextLamp=Lamp.valueOf(next);
nextLamp.light();
System.out.println("绿灯从-"+name()+"方向切换为:"+next+"方向");
}
return nextLamp;//让下一个灯变绿,并且返回此绿灯,为的是要在控制器中,能够改变指示当前灯值:
}
}
灯的控制器类
package Traffic_system;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class lampContraler
{//灯的控制系统
private Lamp contraller;//指示当前的灯
public lampContraler()
{
contraller=Lamp.S2N;
contraller.light();//让当前的灯变绿
//
ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable()
{
@Override
public void run()
{//每隔10秒,就让当前的灯变红,把当前灯变红,就要刷新当前的灯代表的是谁(就是更换当前灯指示的对象,也就要指向先一个灯)
contraller=contraller.unlight();//让当前灯变红后,还要从返回值中得到,下一个绿灯时谁;
}
},
10,
10,
TimeUnit.SECONDS);
}
}
测试类
package Traffic_system;
public class Testmain
{
public static void main(String[] args)
{
//创建12条路的对象
String[] directions=new String[]{
"S2N","S2W","E2W","E2S",
"N2S","N2E","W2E","W2N",
"S2E","E2N","N2W","W2S"
};
for (int i = 0; i < directions.length; i++)
{
new Road(directions[i]);
}
//创建灯的控制器
new lampContraler();
}
}
———–android培训、java培训、java学习型技术博客、期待与您交流!————