Java課程設(shè)計(jì)-地鐵換乘_第1頁(yè)
Java課程設(shè)計(jì)-地鐵換乘_第2頁(yè)
Java課程設(shè)計(jì)-地鐵換乘_第3頁(yè)
Java課程設(shè)計(jì)-地鐵換乘_第4頁(yè)
Java課程設(shè)計(jì)-地鐵換乘_第5頁(yè)
已閱讀5頁(yè),還剩13頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第1章課題概述1.1課題的目的地鐵是大城市人們?nèi)粘I畛鲂械闹匾煌üぞ摺5浅鞘薪煌ㄙY源有限,為引導(dǎo)旅客合理利用線路資源,解決交通瓶頸問(wèn)題,該城市制定了票價(jià)策略:1.每條線路可以單獨(dú)購(gòu)票,票價(jià)不等。2.允許購(gòu)買(mǎi)某些兩條可換乘線路的聯(lián)票。聯(lián)票價(jià)格低于分別購(gòu)票。為了方便使市民出行,通過(guò)編寫(xiě)程序構(gòu)建圖形界面為大家提供最優(yōu)票價(jià)的乘車(chē)方案。1.2課題的要求1.2.1輸入輸出的要求(1)程序運(yùn)行后通過(guò)讀取票價(jià)及站點(diǎn)文件將所有的站點(diǎn)列出,并構(gòu)建起、終點(diǎn)站文本輸入窗口,票價(jià)方案文本輸出窗口。(2)起點(diǎn)站,終點(diǎn)站應(yīng)能夠從鍵盤(pán)輸入,并且可以通過(guò)按鍵不斷重復(fù)輸入、輸出。(3)用戶每次輸入數(shù)據(jù)并通過(guò)提示文本確認(rèn)后點(diǎn)擊“確認(rèn)”按鈕,立即輸出票價(jià)及乘車(chē)方案。(4)方案的輸出符合示例要求,所給出的方案是票價(jià)最低的方案,如用戶輸入:五棵松,霍營(yíng),程序輸出:-(線1,線10)-線8=565。(5)點(diǎn)擊窗口關(guān)閉按鈕后退出程序。1.2.2程序?qū)崿F(xiàn)的功能要求(1)將地鐵站網(wǎng)絡(luò)通過(guò)String[][]二維數(shù)組存儲(chǔ),票價(jià)通過(guò)單線票類和套票類分別存儲(chǔ)。(2)給出獲取換乘站,各類票價(jià),線名等方法。(3)構(gòu)建圖形界面提供可視化的操作界面。(4)對(duì)錯(cuò)誤的輸入發(fā)出提示信息,要求重新輸入。第2章概要設(shè)計(jì)2.1整個(gè)程序的模塊結(jié)構(gòu)及重點(diǎn)分析。本課題所涉及的難點(diǎn)有兩個(gè)分別是1.數(shù)據(jù)的讀取與存儲(chǔ)2.主算法的設(shè)計(jì)。根據(jù)對(duì)java程序一年來(lái)的學(xué)習(xí)并結(jié)合課題要求,我將整個(gè)程序的模塊分為:1.地鐵站名數(shù)據(jù)讀取及存儲(chǔ)模塊。2.票價(jià)數(shù)據(jù)讀取及存儲(chǔ)。3.圖形界面的架構(gòu)。4.主函數(shù)。將每個(gè)模塊寫(xiě)入一個(gè)class文件,并通過(guò)方法而調(diào)用來(lái)實(shí)現(xiàn)程序的運(yùn)行。圖2-1整個(gè)程序的四大模塊2.2數(shù)據(jù)的讀取與存儲(chǔ)結(jié)構(gòu)概述2.2.1數(shù)據(jù)的讀取文件的讀取是IO章節(jié)的內(nèi)容,在這學(xué)期我已經(jīng)多次練習(xí)過(guò)并且很熟練了。我在這選擇了FileReader提供的方法來(lái)讀取文件的字節(jié)流數(shù)據(jù),接著重新構(gòu)建字符串,最后用String類提供的split方法將站名、票價(jià)分解開(kāi)。2.2.2數(shù)據(jù)的存儲(chǔ)如何將數(shù)據(jù)合理的存儲(chǔ),使得主函數(shù)在調(diào)用時(shí)方便是這個(gè)課題的一個(gè)重點(diǎn),但由于我還沒(méi)有學(xué)習(xí)過(guò)數(shù)據(jù)結(jié)構(gòu),所以只能將數(shù)組與數(shù)據(jù)結(jié)合起來(lái)思考。(1)地鐵網(wǎng)絡(luò)首先由于文件存儲(chǔ)的地鐵站名是字符串,戶輸入的起終點(diǎn)格式也是字符串所以基本不用改變地鐵站名的數(shù)據(jù)類型。其次因?yàn)榈罔F站有1.在哪條線上2.在這條線的哪個(gè)位置這兩個(gè)特性,所以我選擇了String[][]二維數(shù)組來(lái)存儲(chǔ),一維下標(biāo)表示該地鐵站所在的線名,二維下標(biāo)表示該地鐵站在該線的位次。(2)票價(jià)由于課題要求計(jì)算最劃算的票價(jià),所以票價(jià)需存儲(chǔ)為int類型以方便計(jì)算。接下來(lái)因?yàn)榇嬖趩尉€票價(jià)和套票的區(qū)別,所以我將單線票價(jià)和套票分成兩個(gè)類:SubwayPriceType1(單線),SubwayPriceType2(套票)來(lái)寫(xiě)(方便調(diào)用的時(shí)候區(qū)分)。因?yàn)樵谧x取數(shù)據(jù)的時(shí)候已經(jīng)將2種票價(jià)分成了2個(gè)數(shù)據(jù)流,所以將單線票價(jià)以int[]數(shù)組來(lái)存儲(chǔ),一維下標(biāo)表示線名,套票以int[][]二維數(shù)組來(lái)存儲(chǔ),一維下標(biāo)表示換乘前站,二維下標(biāo)表示換乘后站。這樣數(shù)據(jù)就以合理的形式存儲(chǔ)了,為主方法的調(diào)用做好準(zhǔn)備。2.3圖形界面概述圖形界面是我通過(guò)自學(xué)《Eclipse的開(kāi)發(fā)技術(shù)詳解》一書(shū)中的SWT章節(jié)來(lái)進(jìn)行架構(gòu)的,由于是自學(xué)所以參照的是計(jì)算器的圖形界面進(jìn)行設(shè)計(jì)的。2.3.1地鐵站名的列出將地鐵站名按線分組依次創(chuàng)建按鈕,只將其作為展示所以沒(méi)有添加監(jiān)聽(tīng)器。2.3.2輸入輸出文本框的構(gòu)建文本框我使用了TEXT類來(lái)進(jìn)行構(gòu)建,輸入文本框給用戶提供了輸入界面,輸出文本框我設(shè)計(jì)了2個(gè),分別是輸入數(shù)據(jù)的復(fù)核框和最終方案的輸出框。復(fù)核框提供給用戶在按下按鍵“確認(rèn)”之前檢查自己輸入是否合法的檢查機(jī)會(huì)。輸出框用來(lái)呈現(xiàn)通過(guò)主函數(shù)獲得的最終的票價(jià)。2.3.3確認(rèn)和取消按鈕的構(gòu)建“確認(rèn)”按鈕是本課題的重中之重,用戶按鍵后將輸入框獲取的數(shù)據(jù)通過(guò)主函數(shù)的計(jì)算獲得方案和票價(jià)?!叭∠卑存I則是提供給用戶一個(gè)清除數(shù)據(jù)再輸入的接口。2.4主函數(shù)概述在設(shè)計(jì)之初我就將主函數(shù)定義為:獲取起點(diǎn)站,終點(diǎn)站站名,返回字符串給最終方案輸出框的方法。由于主函數(shù)過(guò)于復(fù)雜,在此不再贅述,詳細(xì)參看3.4節(jié)。第3章程序功能的實(shí)現(xiàn)3.1地鐵各站數(shù)據(jù)的讀取與存儲(chǔ)結(jié)構(gòu)的實(shí)現(xiàn)3.1.1數(shù)據(jù)讀取使用了FileReader,代碼如下:FileReaderfis=newFileReader("station.txt");//本段是站名文件,票價(jià)類似。for(intb=0;b>=0;b++) { b=fis.read(); if(b==-1) { break; } else { FileData.addElement(b); continue; }}3.1.2存儲(chǔ)地鐵站名Lines是一個(gè)Vector<Stirng>類型的對(duì)象,是將數(shù)據(jù)分解后存儲(chǔ)有各條線路所有站名的向量(沒(méi)有站的線路依然在向量中占據(jù)一個(gè)位置,值為null),其中的每一個(gè)元素是一條線的所有站的站名,通過(guò)雙重循環(huán)向String[][]中賦值,代碼如下():String[][]S1=newString[lines.size()][]; for(inti=0;i<lines.size();i++) { String[]S2=lines.get(i).split("\r\n"); S1[i]=newString[S2.length]; for(intj=0;j<S2.length;j++) { S1[i][j]=S2[j]; }}3.1.3地鐵網(wǎng)絡(luò)數(shù)據(jù)提供的方法(1)返回經(jīng)過(guò)此戰(zhàn)的所有線路的線名的數(shù)組方法有兩個(gè)不同參數(shù)的方法,第一個(gè)方法能將當(dāng)前線名放在0號(hào)元素,第二個(gè)方法則是直接返回經(jīng)過(guò)的所有線名并將其從小到大排列,代碼如下:publicint[]getLinesNo(Stringstationname,intlineno) { line1.setStations(); crossstation=newVector<Integer>(); crossstation.addElement(lineno); for(inti=0;i<line1.S1.length;i++) { for(intj=0;j<line1.S1[i].length;j++) { if(stationname.equals(line1.S1[i][j])&i!=lineno) { crossstation.addElement(i); } } } int[]linesno=newint[crossstation.size()]; for(inti=0;i<crossstation.size();i++) { linesno[i]=crossstation.get(i); } returnlinesno; } publicint[]getLinesNo(Stringstationname) { line1.setStations(); crossstation=newVector<Integer>(); for(inti=0;i<line1.S1.length;i++) { for(intj=0;j<line1.S1[i].length;j++) { if(stationname.equals(line1.S1[i][j])) { crossstation.addElement(i); } } } int[]linesno=newint[crossstation.size()]; for(inti=0;i<crossstation.size();i++) { linesno[i]=crossstation.get(i); } returnlinesno;}(2)判斷兩條線是否能換乘的方法因?yàn)樵诓榭丛磾?shù)據(jù)的時(shí)候我發(fā)現(xiàn),存在兩條線能換乘但沒(méi)有套票的情況,為了了滿足這種情況,編寫(xiě)了代碼如下的方法,返回一個(gè)boolean值:publicbooleanLineCango(inta,intb) { line1.setStations(); booleanc=false; for(inti=0;i<line1.S1[a].length;i++) { for(intj=0;j<line1.S1[b].length;j++) { if(line1.S1[a][i].equals(line1.S1[b][j])) { c=true; } } } returnc;}3.2單線票價(jià)和套票的數(shù)據(jù)讀取與存儲(chǔ)3.2.1單線票價(jià)存儲(chǔ)單線票價(jià)是通過(guò)int[]數(shù)組來(lái)存儲(chǔ)的。代碼中的subwaypricetype1是一個(gè)Vector<String>類型的對(duì)象,是將數(shù)據(jù)分解后存有所有單線票價(jià)的向量。方法中我通過(guò)單循環(huán)向int[]中賦值。其中我對(duì)線名進(jìn)行了解析,使得例如10號(hào)線的票價(jià)就存儲(chǔ)在10號(hào)元素中,從而使得調(diào)用方便。代碼如下:publicvoidsetSubwayPriceType1() { intlength=subwaypricetype1.size();subwaypricetype1.setSize(Integer.parseInt(subwaypricetype1.lastElement().substring(1,3))+1); for(inti=(length-1);i>=0;i--) { subwaypricetype1.set(Integer.parseInt(subwaypricetype1.get(i).substring(1,3)),subwaypricetype1.get(i)); subwaypricetype1.set(i,null); } for(inti=0;i<subwaypricetype1.size();i++) { if(subwaypricetype1.get(i)==null) { subwaypricetype1.set(i,"000000000000"); } } int[]S1=newint[subwaypricetype1.size()]; for(inti=1;i<subwaypricetype1.size();i++) { S1[i]=Integer.parseInt(subwaypricetype1.get(i).substring(4,subwaypricetype1.get(i).length())); } this.S1=S1; }3.2.2套票的存儲(chǔ)相對(duì)于單線來(lái)說(shuō)套票需要有2個(gè)元素,換乘前站和換乘后站,所以我將套票存儲(chǔ)在一個(gè)int[][]二維數(shù)組中,通過(guò)雙重循環(huán)向int[][]中賦值。代碼段中的subwaypricetype2是一個(gè)Vector<String>類型的對(duì)象,是將數(shù)據(jù)分解后存有所有套票票價(jià)的字符串向量。其中我也對(duì)線名進(jìn)行了解析,使得例如10,8號(hào)線的套票就存在int[8][10]號(hào)元素中,方便方法調(diào)用。代碼如下:publicvoidsetSubwayPriceType2() { String[][]T1=newString[subwaypricetype2.size()][]; for(inti=0;i<subwaypricetype2.size();i++) { T1[i]=subwaypricetype2.get(i).split("");S1[Integer.parseInt(T1[i][0].substring(1,3))][Integer.parseInt(T1[i][1].substring(1,3))]=Integer.parseInt(T1[i][2].substring(0,T1[i][2].length())); }}3.2.3票價(jià)數(shù)據(jù)提供的方法因?yàn)楸绢}中一個(gè)人在一條線路上不管怎么乘坐價(jià)格是不變的,所以我編寫(xiě)了通過(guò)傳入線名的int值來(lái)調(diào)用票價(jià)的方法,代碼如下:publicintgetLinePrice(intlineno) { returnS1[lineno][0];} publicintgetDiscountPrice(intlineno1,intlineno2) { returnS1[lineno1][lineno2];}3.3窗口的構(gòu)建3.3.1站名的列出通過(guò)添加按鍵的方式將站名展示在窗口中,代碼如下:publicvoidpaintStationList(inti) { GridLayoutlist=newGridLayout(); list.numColumns=12; list.makeColumnsEqualWidth=true; list.horizontalSpacing=5; list.marginWidth=0; list.marginHeight=5; stationlist.setLayout(list); stationlist.setLayoutData(newGridData(GridData.FILL_VERTICAL)); for(intj=0;j<line1.S1[i].length;j++) { Buttonstation=newButton(stationlist,SWT.NONE); station.setText(line1.S1[i][j]); GridDatagridData=newGridData(); gridData.horizontalAlignment=SWT.FILL; gridData.verticalAlignment=SWT.FILL; station.setLayoutData(gridData); }}圖3-1站名的列出3.3.2文本框的構(gòu)建文本框有三個(gè)分別是輸入框,復(fù)核框,輸出框,按照課題需要,編寫(xiě)代碼如下:publicvoidpaintPriceOutputFrame() { FillLayoutframe=newFillLayout(SWT.HORIZONTAL); frame.marginHeight=5; priceoutputframe.setLayout(frame);priceoutputframe.setLayoutData(newGridData(GridData.FILL_HORIZONTAL)); text=newLabel(priceoutputframe,SWT.BORDER|SWT.LEFT); RGBrgb=newRGB(255,255,255); Colorcc=newColor(display,rgb); text.setBackground(cc); Fontfont=newFont(display,"Arial",14,SWT.NORMAL); text.setFont(font); text.setText("Example:-線01-(線04,線13)=440"); } publicvoidpaintStrategyInputFrame() {strategyinputframe.setLayoutData(newGridData(GridData.FILL_HORIZONTAL)); strategyinputframe.addVerifyListener(newMyListener()); } publicvoidpaintThatStrategyFrame() {thatstrategyframe.setLayoutData(newGridData(GridData.FILL_HORIZONTAL)); thatstrategyframe.setEditable(false);}圖3-2文本框的構(gòu)建3.3.3按鍵的構(gòu)建為了實(shí)現(xiàn)按鍵后輸出票價(jià)方案,就要實(shí)現(xiàn)按鍵的響應(yīng)和主函數(shù)的調(diào)用。其中newMainMethod(origination,destination).getStrategy()就是獲取方案和票價(jià)的方法。按鈕的構(gòu)建和監(jiān)聽(tīng)器的代碼如下:publicvoidpaintButtons() { FillLayoutlist=newFillLayout(); list.type=SWT.HORIZONTAL; list.marginWidth=0; list.marginHeight=5; buttons.setLayout(list);buttons.setLayoutData(newGridData(GridData.FILL_HORIZONTAL)); Buttonaye=newButton(buttons,SWT.PUSH); aye.setText("確認(rèn)"); aye.addSelectionListener(newMyListener()); Buttoncancel=newButton(buttons,SWT.NONE); cancel.setText("清除"); cancel.addSelectionListener(newMyListener());}publicvoidwidgetSelected(SelectionEventarg0) { Buttonwhether=(Button)arg0.getSource(); Stringthat=whether.getText(); if(that.equals("確認(rèn)")) { try { stations=thatstrategyframe.getText().split(","); origination=stations[0]; destination=stations[1]; text.setText(newMainMethod(origination,destination).getStrategy()); } catch(Exceptione) { text.setText("本系統(tǒng)尚未完善,交換起、終點(diǎn)站或選擇附近站點(diǎn)輸入再試。"); } } else//按鍵是“取消的情況”。 { text.setText("數(shù)據(jù)已清除。"); strategyinputframe.setText(""); }}圖3-2按下“取消”的效果3.4主函數(shù)的編寫(xiě)3.4.1站名轉(zhuǎn)換為線名上面說(shuō)過(guò)票價(jià)數(shù)據(jù)提供的方法是傳入線名返回票價(jià),所以第一步將站名轉(zhuǎn)化為線名,我們通過(guò)調(diào)用getLinesNo方法來(lái)獲取經(jīng)過(guò)該站的所有線名,代碼如下:int[]a=crossstation.getLinesNo(origination);int[]b=crossstation.getLinesNo(destination);3.4.2方案的遍歷因?yàn)槠?、終點(diǎn)站都有可能是換乘站,所以獲取的經(jīng)過(guò)的所有線路的線名是一個(gè)數(shù)組,我們通過(guò)遍歷數(shù)組來(lái)計(jì)算所有的方案,代碼如下:for(inti=0;i<a.length;i++) { for(intj=0;j<b.length;j++) { intlineno1=a[i]; intlineno2=b[j];//未完3.4.3方案的計(jì)算在這個(gè)計(jì)算中我把所有能夠到達(dá)的方案和票價(jià)添加進(jìn)兩個(gè)向量ways和prices之中,在最后再通過(guò)比較輸出最劃算的方案(1)在同一條線上的情況if(lineno1==lineno2) { ways.addElement("線"+lineno1+"="); prices.addElement(subwaypricetype1.getLinePrice(lineno1));}(2)不在同一條線上但兩線有套票if(subwaypricetype2.getDiscountPrice(lineno1,lineno2)!=0) { prices.addElement(subwaypricetype2.getDiscountPrice(lineno1,lineno2)); ways.addElement("(線"+lineno1+",線"+lineno2+")=");}(3)不在同一條線上能換乘但沒(méi)有套票if(crossstation.LineCango(lineno1,lineno2)){ prices.addElement(subwaypricetype1.getLinePrice(lineno1)+subwaypricetype1.getLinePrice(lineno2)); ways.addElement("線"+lineno1+",線"+lineno2+"=");}(4)需要中間站的情況(代碼量過(guò)大貼出后看不清,參看源代碼MainMethod.class中60-120行):(5)所有情況列出后獲取最劃算方案(代碼類似于(6)):(6)在(1)過(guò)程結(jié)束后再進(jìn)行一次最劃算方案的計(jì)算intfinalprice=complexprice.get(0);; if(complexprice.size()==1) { T=complexstrategy.get(0)+complexprice.get(0); } else { for(intk=1;k<complexprice.size();k++) { finalprice=finalprice<complexprice.get(k)?finalprice:complexprice.get(k); } for(intk=0;k<complexprice.size();k++) { if(finalprice==complexprice.get(k)) { T=complexstrategy.get(k)+complexprice.get(k); } }}這樣T(String)就傳給了文本輸出框。第4章程序測(cè)試及分析運(yùn)行程序,窗口呈現(xiàn)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論