最完整的合並相交集合的Java代碼(查並集)


這個是自己寫的算法,如果有大牛,麻煩幫我並行化。初學者則可以學到不少東西。

產生測試用例

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");
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM