递归求地铁两站间最短路径

long time no bo 了!文明点!此博非彼bo!

记录一个刚刚完成的题目——

根据某市地铁线路图写一个地铁票价计算程序

需求描述:

1.计费规则:最低2元,超过5站以上每站加收 0.5元,换乘重新起算,例如L1先坐4站,换乘L2再坐6站,结果就是2+2.5=5.5元

2.程序启动以后读取输入文件(in.txt),内容格式如:

L2-8,L2-2

X3,L3-8

....

每行表示一次行程,起点站和终点站之间用逗号分 隔,行数不限

4.系统按最短路径方案(尽量少换乘且站数少,假设乘 客换乘一次用的时间相当于坐4个站)规划路线,计算票价,并把路线和票价输出到文件(out.txt),内容格式如:

L2-8,L2-2=2.5:L2-8,L2-7,L2-6,L2-5,L2-4,L2-3,L2-2

X3,L3-8=4:X3,X4,L3-8

....

等号后面的表示票价和路径


地铁线路图如下:共有5条线路,X开头的站点表示 换乘车站


我用的是最笨的方法——遍历。存储这个图时我没用传统的矩阵方法。我设置了一个父类是Station,子类是NormalStation和TransportStation。就是普通车站和换乘车站,换乘车站里有一个保存着与它相邻的所有车站的ArrayList。我没有按照题目要求全做完,只做了寻找两个站之间的所有路径,想求最短路径再作计算然后排序就可以了,数据量不大。

算法很简单就是递归遍历与当前车站临近的所有车站,避免遍历已经访问过的车站。想运行的话先在d盘建立一个out.txt。

package com.question.station;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

public class Main {

	static Stack<Station> stack = new Stack<Station>();
	static List<Station> allStations = new ArrayList<Station>();
	static Station start;
	static Station end;
	
	static void iterator(Station now){
		System.out.println("now "+now);

		if( now != null){
			if(now == end){
				System.out.println("find a way");
				FileWriter writer = null;
				try{
					writer = new FileWriter("d:/out.txt",true);
					Iterator<Station> it = stack.iterator();
					while(it.hasNext()){
						writer.write(it.next()+" ");
					}
					writer.write(end.toString());
					writer.write("\r\n");
				}catch (IOException e) {     
		            e.printStackTrace();     
		        } finally {     
		            try {     
		                if(writer != null){  
		                    writer.close();     
		                }  
		            } catch (IOException e) {     
		                e.printStackTrace();     
		            }     
		        }   
				return;
			}
			//如果当前车站为普通车站
			if(now.type.equals(StationTypeEnum.Normal)){
				NormalStation ns = (NormalStation)now;
				//访问下一站
				
				if(!stack.contains(ns.next)){
					stack.push(now);
					iterator(ns.next);
					stack.pop();
				}
				//访问前一站
				else if(!stack.contains(ns.prev)){
					stack.push(now);
					iterator(ns.prev);
					stack.pop();
				}
				else{
					return;
				}
			}
			//如果当前车站为换乘车站
			else{
				
				TransportStation ts = (TransportStation)now;
				
				stack.push(now);
				for(Station s : ts.stations){
					if(!stack.contains(s)){
						iterator(s);
					}
				}
				stack.pop();
			}
		}
	}
	
	public static void main(String[] args) {
		//清空文件
		File f = new File("d:/out.txt");
		FileWriter fw;
		try {
			fw = new FileWriter(f);
			fw.write("");
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		InitStations.init(allStations);
		for(Station s : allStations){
			if(s.name.equals("X3")){
				start = s;
			}
		}
		for(Station s : allStations){
			if(s.name.equals("L3-8")){
				end = s;
			}
		}
		stack.push(start);
		if(start.type.equals(StationTypeEnum.Normal)){
			NormalStation ns = (NormalStation)start;
			if(ns.next!=null){
				iterator(ns.next);
			}
			if(ns.prev!=null){
				iterator(ns.prev);
			}
		}
		else{
			TransportStation ts = (TransportStation)start;
			for(Station s : ts.stations){
				iterator(s);
			}
		}
	}

}

完整工程文件到这里下载:http://download.youkuaiyun.com/detail/songxueyu/7572913

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值