在課堂上通過實驗以後,從新在宿舍裏面從0開始編寫大概30分鐘左右可以完成這個實驗,不是原來的思路。java
該實驗的表述爲:從兩個文本input1.txt和input2.txt中讀取英文單詞,若前面的英文單詞的尾字母和後面的英文單詞的未字母相同的話,則構成一個英文詞語接龍,直到文章結尾,求出整篇文章中詞語接龍最長的詞語接龍詞組,並將其輸出到output1.txt和output2.txt文件夾中。算法
實驗代碼:app
package ctn; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.List; public class Ctn { static List<String> words=new ArrayList<String>(); public static void main(String args[]) throws IOException { words.clear(); if(daoru("input1.txt")) { int size=0; List<String> result = null; while(words.size()>0) { List<String> temp=returnList(words); if(temp.size()>size) { result=temp; size=temp.size(); } } String all=new String(); if(result.size()>1) { for(String it:result) { all+=it+"\r\n"; } daochu(all,"output1.txt"); System.out.println("文件output1.txt導出"); } else System.out.println("單詞數量過少沒法導出"); } else System.out.println("文件input1.txt不存在"); words.clear(); if(daoru("input2.txt")) { int size=0; List<String> result = null; while(words.size()>0) { List<String> temp=returnList(words); if(temp.size()>size) { result=temp; size=temp.size(); } } String all=new String(); if(result.size()>1) { for(String it:result) { all+=it+"\r\n"; } daochu(all,"output2.txt"); System.out.println("文件output2.txt導出"); } else System.out.println("單詞數量過少沒法導出"); words.clear(); } else System.out.println("文件input2.txt不存在"); } public static List<String> returnList(List<String> in) { char cold=0; char cnew=0; List<String> temp=new ArrayList<String>(); List<Integer> tempNum=new ArrayList<Integer>(); for(int i=0;i<in.size();i++) { String now=in.get(i); if(i==0) { cold=now.charAt(now.length()-1); tempNum.add(i); temp.add(now); continue; } cnew=now.charAt(0); if(cold==cnew) { tempNum.add(i); if(!temp.contains(now)) { temp.add(now); cold=now.charAt(now.length()-1); } } } for(int j=tempNum.size()-1;j>=0;j--) { in.remove((int)tempNum.get(j)); } return temp; } public static boolean daoru(String path) throws IOException { File a=new File(path); if(!judeFileExists(a)) { System.out.println("文件不存在"); return false; } FileInputStream b = new FileInputStream(a); InputStreamReader c=new InputStreamReader(b,"UTF-8"); { BufferedReader bufr =new BufferedReader(c); String line = null; while((line = bufr.readLine())!=null){ //line是每一行的數據 String ook[]=line.split("[^A-Za-z]"); for(String it:ook) { //it是每個空格的數據 String temp=it.toLowerCase().replace("\'", "").replace(",", "").replace(".", "").replace(":", "").replace("!", ""); if(temp.length()>0) words.add(temp); } } bufr.close(); } c.close(); b.close(); return true; } //導入文件時判斷文件存在 public static boolean judeFileExists(File file) { if (file.exists()) { return true; } else { return false; } } public static void daochu(String txt,String outfile) throws IOException { File fi=new File(outfile); FileOutputStream fop=new FileOutputStream(fi); OutputStreamWriter ops=new OutputStreamWriter(fop,"UTF-8"); ops.append(txt); ops.close(); fop.close(); } }
該實驗過程當中測試
對input1.txt輸入飄的英文小說的第一章內容,輸出output1.txt的時間響應應該在毫秒級之內。(單詞量1W左右)spa
對input2.txt輸入飄的整本英文小說的內筒後,輸出output2.txt的時間響應應該在5分鐘左右。(單詞量50W左右)code
所以上述代碼的算法對於數的運算過程響應的時間較長,推斷是List中讀取N個數據所耗費的時間太長,可是通過了把代碼修改爲HashMap和Vector對比以後(算法同樣的狀況下),上面的代碼在處理速度已是最優了blog
對於Vector來講:處理1w單詞就須要耗費數秒,對於50w詞的數據就更不用說了rem
對於Map來講:處理1w單詞的時候和List都在1秒之內,50w單詞的處理未通過測試get
Map的成語接龍實驗代碼:input
package ctn; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Ctn2 { static Map<Integer,String> words=null; public static void main(String args[]) throws IOException { //words.clear(); //System.out.println("導入Input1.txt"); words=new HashMap<Integer,String>(); if(daoru("input1.txt")) { //System.out.println("導入成功"); int size=0; Map<Integer,String> result = null; int maxSize=words.size(); while(words.size()>0) { Map<Integer,String> temp=returnMap(words); if(temp.size()>size) { result=temp; size=temp.size(); } } String all=new String(); if(result.size()>1) { for(int i=0;i<maxSize;i++) { if(result.get(i)!=null) all+=result.get(i)+"\r\n"; } daochu(all,"output1.txt"); System.out.println("文件output1.txt導出"); } else System.out.println("單詞數量過少沒法導出"); } else System.out.println("文件input1.txt不存在"); System.out.println("開始清空Words"); words.clear(); System.out.println("Words清空完畢"); System.out.println("導入Input2.txt"); if(daoru("input2.txt")) { System.out.println("導入成功"); int size=0; Map<Integer,String> result = null; int maxSize=words.size(); while(words.size()>0) { Map<Integer,String> temp=returnMap(words); if(temp.size()>size) { result=temp; size=temp.size(); } } String all=new String(); if(result.size()>1) { for(int i=0;i<maxSize;i++) { if(result.get(i)!=null) all+=result.get(i)+"\r\n"; } daochu(all,"output2.txt"); System.out.println("文件output2.txt導出"); } else System.out.println("單詞數量過少沒法導出"); } else System.out.println("文件input2.txt不存在"); } //將元素對應到Map上,如何判斷已經檢查過? public static Map<Integer,String> returnMap(Map<Integer,String> in) { char cold=0; char cnew=0; Map<Integer,String> temp=new HashMap<Integer,String>(); List<Integer> tempNum=new ArrayList<Integer>(); boolean g_firstStart=false; int g_start=0; for(Integer i:in.keySet()) { if(!g_firstStart) { g_firstStart=true; g_start=i; } String now=in.get(i); if(i==g_start) { cold=now.charAt(now.length()-1); temp.put(i, now); tempNum.add(i); continue; } cnew=now.charAt(0); if(cold==cnew) { temp.put(i, now); tempNum.add(i); cold=now.charAt(now.length()-1); } } for(Integer z:tempNum) { in.remove(z); } return temp; } public static boolean daoru(String path) throws IOException { File a=new File(path); if(!judeFileExists(a)) { System.out.println("文件不存在"); return false; } FileInputStream b = new FileInputStream(a); InputStreamReader c=new InputStreamReader(b,"UTF-8"); { BufferedReader bufr =new BufferedReader(c); String line = null; Integer i=0; while((line = bufr.readLine())!=null){ //line是每一行的數據 String ook[]=line.split("[^A-Za-z]"); for(String it:ook) { //it是每個空格的數據 String temp=it.toLowerCase().replace("\'", "").replace(",", "").replace(".", "").replace(":", "").replace("!", ""); if(temp.length()>1) { words.put(i,temp); i+=1; } } } bufr.close(); } c.close(); b.close(); return true; } //導入文件時判斷文件存在 public static boolean judeFileExists(File file) { if (file.exists()) { return true; } else { return false; } } public static void daochu(String txt,String outfile) throws IOException { File fi=new File(outfile); FileOutputStream fop=new FileOutputStream(fi); OutputStreamWriter ops=new OutputStreamWriter(fop,"UTF-8"); ops.append(txt); ops.close(); fop.close(); } }
在算法方面我找不到更優的解法,對於老師要求的幾百W個單詞中詞語接龍的算法,仍是得進一步探索後才能知道,雖然單詞讀入的過程當中不會死機,可是要想在1分鐘內實現百萬級別的單詞的找出最長的成語接龍還須要很長的1段路須要走。
如今暫時掛起,之後有能力再繼續挑戰。