這個是自己寫的算法,如果有大牛,麻煩幫我並行化。初學者則可以學到不少東西。
產生測試用例
import java.io.*;
import java.util.Random;
public class ProduceCase {
public static void main(String[] argvs){
File file2 = new File("D:\\YounG\\TestCases\\MySet\\test.txt");
FileWriter fw = null;
BufferedWriter writer = null;
try {
fw = new FileWriter(file2);
writer = new BufferedWriter(fw);
for(int i = 0; i < 500000; i++){
StringBuilder stringBuilder = new StringBuilder();
Random random = new Random();
for(int j = 0; j < random.nextInt(21); j++){
String s = getRandomString();
if(" ".equals(s)&&s.isEmpty()) continue;
stringBuilder.append(s + " ");
}
writer.write(stringBuilder.toString());
writer.newLine();//換行
}
writer.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally{
try {
writer.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static String getRandomString( ) { //length表示生成字符串的長度
Random random = new Random();
StringBuilder sb = new StringBuilder();
int length = random.nextInt(10);
for (int i = 0; i < length; i++) {
int number = random.nextInt(26);
sb.append(String.valueOf((char) (number+65) ));
}
return sb.toString();
}
}
合並集合:
import java.io.*; import java.util.*; public class MapTest { public static void main(String[] argvs) { File file = new File("D:\\YounG\\TestCases\\MySet\\test.txt"); BufferedReader reader = null; List<HashSet> mySets = new ArrayList<>(500000); boolean hasEmpty = false; try { reader = new BufferedReader(new FileReader(file)); String tempString; // 一次讀入一行,直到讀入null為文件結束 while ((tempString = reader.readLine()) != null) { // 顯示行號 Scanner scanner = new Scanner(tempString); HashSet<String> mySet = new HashSet<>(); mySet.clear(); while (scanner.hasNext()) { mySet.add(scanner.next()); } scanner.close(); //對個集合內部進行排序,定義大小。放棄排序。 if (mySet.isEmpty() && !hasEmpty) hasEmpty = true; else mySets.add(mySet); } reader.close(); } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e1) { } } } List<Integer> destList = new ArrayList<>(mySets.size()); int setsSize = mySets.size(); for (int i = 0; i < setsSize; ++i) { destList.add(i); } Map<String,Integer> mergeMap = new HashMap<>(1000000); //合並圖。 long startTime=System.currentTimeMillis(); //獲取開始時間 for (int setId = 0; setId < mySets.size(); ++setId) { Iterator<String> iterator = mySets.get(setId).iterator(); List<String> setElem = new ArrayList<>(50);//先把元素全部迭代出來,避免了多線程錯誤。 while (iterator.hasNext()) setElem.add(iterator.next()); int elemNumOfSet = setElem.size(); for(int j = 0; j < elemNumOfSet; j++) { if( mergeMap.containsKey( setElem.get(j) ) ) { //判斷當前元素是否包含在合並記錄表里邊。永遠不要用直接下標訪問(偽下標) Integer destValueSetId = destList.get( mergeMap.get( setElem.get(j) ).intValue() ); //真實 的包含該元素的最小集合號。 Integer destLoopSetId = destList.get(setId); if( destValueSetId.compareTo( destLoopSetId ) > 0 ) { // Iterator putIterator = mySets.get(destValue).iterator(); // while (putIterator.hasNext()) // mergeMap.put((String) putIterator.next(), destList.get(setId)); //找過的元素記得入mergeMap。 mySets.get( destLoopSetId ).addAll( mySets.get(destValueSetId) );//Set中元素增多,所以iterator失效,故重新復制。且Hash 存儲本身就是無序的,隨着元素的增加是會改動存儲順序的。 //推測,HashSet與HashMap不同HashSet不過就是所有的Value是一個固定的地址罷了。而HashMap分為了Value和Key兩個集合。 mySets.get( destValueSetId ).clear(); for (int i = 0; i < destList.size(); i++) { if ( destList.get(i).equals( destValueSetId ) ) { destList.set(i, destLoopSetId ); } } } else if(destValueSetId.compareTo( destLoopSetId ) < 0) { // Iterator putIterator = mySets.get(destValue).iterator(); // while (putIterator.hasNext()) // mergeMap.put((String) putIterator.next(), destValue); //找過的元素記得入mergeMap。 mySets.get( destValueSetId ).addAll( mySets.get(destLoopSetId)); mySets.get( destLoopSetId ).clear(); for (int i = 0; i < destList.size(); i++) { if ( destList.get(i).equals( destLoopSetId )) { destList.set(i, destValueSetId); } } } } else { mergeMap.put( setElem.get(j) , setId ); //此處切記不可用destList.get(iSet),因為該值並不穩定。 } } } long endTime=System.currentTimeMillis(); //獲取結束時間 System.out.println("程序運行時間: "+(endTime-startTime)+"ms"); Iterator iterator = mySets.iterator(); File file2 = new File("D:\\YounG\\TestCases\\MySet\\testACK.txt"); FileWriter fw = null; BufferedWriter writer = null; try { fw = new FileWriter(file2); writer = new BufferedWriter(fw); while(iterator.hasNext()){ HashSet<String> temp = (HashSet<String>) iterator.next(); if(!temp.isEmpty()) { writer.write( temp.toString() ); writer.newLine(); } } writer.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); }finally{ try { writer.close(); fw.close(); } catch (IOException e) { e.printStackTrace(); } } } }
驗證輸出結果:
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.*; import java.util.regex.Pattern; /** * Created by Young on 2015/12/25. * 如何測試測試用例: * 1.所有的元素不重復,/hashSet * 2.元素的種類不減少,/count * 3.沒有非法合並。(非法合並指,合並過程中,不存在共同元素依然合並),這一項適合在合並程序必然實現。 * 3 must be true since contains and addAll execute as the same time. */ public class Validaty { public static void main(String[] args) { File file = new File("D:\\YounG\\TestCases\\MySet\\testACK.txt"); BufferedReader reader = null; Set allSet = new HashSet<String>(); //int count1 = 0; try { reader = new BufferedReader(new FileReader(file)); String tempString; // 一次讀入一行,直到讀入null為文件結束 allSet.clear(); while ((tempString = reader.readLine()) != null) { // 顯示行號 tempString = tempString.substring(1,tempString.length()-1); //Pattern pattern = Pattern.compile(","); String[] strings = tempString.split(", "); int strj = 0; while (strj < strings.length && !strings[strj].isEmpty()){ if (allSet.contains(strings[strj])) { System.out.println("Wrong ACK for \"" + strings[strj] + "\" is repeated"); return; } allSet.add(strings[strj]); strj++; } /* Scanner scanner = new Scanner(tempString); while (scanner.hasNext()) { String temp = scanner.next(); if (allSet.contains(temp)) { System.out.println("Wrong ACK for " + temp + "is repeated"); return; } allSet.add(temp); //++count1; } scanner.close();*/ } reader.close(); } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e1) { } } } File file2 = new File("D:\\YounG\\TestCases\\MySet\\test.txt"); BufferedReader reader2 = null; try { reader2 = new BufferedReader(new FileReader(file2)); String tempString; // 一次讀入一行,直到讀入null為文件結束 while ((tempString = reader2.readLine()) != null) { // 顯示行號 Scanner scanner = new Scanner(tempString); while (scanner.hasNext()) { String temp = scanner.next(); if (!allSet.contains(temp)) { System.out.println("Wrong ACK for lost elem " + temp); return; } } scanner.close(); } reader2.close(); } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e1) { } } } System.out.println("Right ACK"); } }
