码迷,mamicode.com
首页 > 编程语言 > 详细

统计两组数据的交集和补集(新旧数据的差异比较算法)遍历一次

时间:2015-08-27 12:51:06      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:


旧数据A = {}
新数据B = {}

新增项:B - A = { x | x∈B且x∉A}
删除项:A - B = { x | x∈A且x∉B}
共有项:B ∩ A = { x | x∈B且x∈A}

 技术分享

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class RecordDiff {
    public static void main(String[] args) {

        // 根据新数据对旧数据的改变进行统计:新旧项来自数据库约束为自增长整数的原始键字段,即不重复整数,已升序排序

        Integer[] as = new Integer[] { 1, 2, 3, 8, 9, 12 };
        Integer[] bs = new Integer[] { 1, 2, 3, 9, 10, 12, 18, 22 };
        // bs = new Integer[] { 1, 2, 3, 9 };
        System.out.println("旧项:" + Arrays.toString(as));
        System.out.println("新项:" + Arrays.toString(bs));
        System.out.println("====================");
        List<Integer> aList = Arrays.asList(as);// old data
        List<Integer> bList = Arrays.asList(bs);// new data

        Diff<Integer> diff1 = Diff.difference(aList, bList);

        System.out.println("都有项:" + Arrays.toString(diff1.unionList.toArray()));
        System.out.println("新增项:" + Arrays.toString(diff1.addedList.toArray()));
        System.out.println("删除项:" + Arrays.toString(diff1.removedList.toArray()));
        System.out.println("====================");

        List<Integer> fromOnlyList = new ArrayList<Integer>();
        List<Integer> againstOnlyList = new ArrayList<Integer>();
        List<Integer> bothList = new ArrayList<Integer>();
        Diff.diff(aList, bList, fromOnlyList, againstOnlyList, bothList);
        System.out.println("都有项:" + Arrays.toString(bothList.toArray()));
        System.out.println("新增项:" + Arrays.toString(againstOnlyList.toArray()));
        System.out.println("删除项:" + Arrays.toString(fromOnlyList.toArray()));
    }

    /**
     * 对两组数据进行差异比较,得出新旧的差异:都有项,新增项,删除项
     * 
     * @author fangss
     *
     * @param <T>
     */
    public static class Diff<T extends Comparable<T>> {
        /** 共有项 */
        List<T> unionList;
        /** 差异项 */
        List<T> addedList, removedList;

        /**
         * 
         * @param unionList
         *          接受都有项的结果Buffer
         * @param addedList
         *          接受新增项的结果Buffer
         * @param removedList
         *          接受删除项的结果Buffer
         */
        public Diff(List<T> unionList, List<T> addedList, List<T> removedList) {
            super();
            this.unionList = unionList;
            this.addedList = addedList;
            this.removedList = removedList;
        }

        /**
         * 新旧数据列表两个都只遍历一次,适用于数据只能向前滚动一次,如读文件行 <br>
         * A B 6 1 7 \ 2 8 \ 3 9 \ 5 10 . 6 11 . 10 12 16 17 18
         * 
         * @param fromList
         *          必须有序,且升序,一般是旧数据, The List to compare from
         * @param againstList
         *          必须有序,且升序,一般是新数据 A List to compare against
         * @param fromOnlyList
         *          补集
         * @param againstOnlyList
         *          补集
         * @param bothList
         *          交集
         */
        public static <T extends Comparable<T>> void diff(List<T> fromList, List<T> againstList, List<T> fromOnlyList,
                List<T> againstOnlyList, List<T> bothList) {

            // 0 - both, ‘f‘ - from, ‘a‘ - against, 和比较结果一致:一样大小都移动,否则谁小谁移动
            int whoMakeWay = ‘b‘;
            Iterator<T> fromIterator = fromList.iterator();
            Iterator<T> againstIterator = againstList.iterator();

            T from = null, against = null;
            while (true) {
                T fromNext = null;
                if (‘a‘ != whoMakeWay) {
                    if (hasNextOrExhaustRival(fromIterator, null, againstIterator, againstOnlyList)) {
                        from = fromIterator.next();
                        fromNext = from;
                    } else {
                        return;
                    }
                }
                if (‘f‘ != whoMakeWay) {
                    if (hasNextOrExhaustRival(againstIterator, fromNext, fromIterator, fromOnlyList)) {
                        against = againstIterator.next();
                    } else {
                        return;
                    }
                }
                // 先两个都判断有下一个,然后再移动,否则先移动有下一个而另一个没有,前一个仅自己有的就丢失一项
                int cmpResult = from.compareTo(against);
                // 谁小移动谁,一样就都移动。
                if (0 == cmpResult) {
                    whoMakeWay = ‘b‘;
                    bothList.add(from);
                } else if (0 > cmpResult) {
                    // from < against: fromIterator continue until 持平0或超过1
                    whoMakeWay = ‘f‘;
                    fromOnlyList.add(from);
                } else {
                    // from > against: againstIterator continue until 持平0或超过1
                    whoMakeWay = ‘a‘;
                    againstOnlyList.add(against);
                }
            }

        }

        public static <T extends Comparable<T>> boolean hasNextOrExhaustRival(Iterator<T> hasNext, T rivalCurVal,
                Iterator<T> rival, List<T> list) {
            if (hasNext.hasNext()) {
                return true;
            }
            if (null != rivalCurVal) {
                list.add(rivalCurVal);
            }
            while (rival.hasNext()) {
                list.add(rival.next());
            }
            return false;
        }

        /**
         * 新旧数据列表两个遍历可能不只一次
         * 
         * @param newList
         *          必须有序,且升序
         * @param oldList
         *          必须有序,且升序
         * @param unionList
         * @param addedList
         * @param removedList
         */
        private static <T> void innerDifference(List<T> newList, List<T> oldList, List<T> unionList, List<T> addedList,
                List<T> removedList) {
            for (Iterator<T> iterator = removedList.iterator(); iterator.hasNext();) {
                T item = iterator.next();
                if (addedList.contains(item)) {
                    unionList.add(item);
                    iterator.remove();
                    addedList.remove(item);
                }
            }
        }

        /**
         * 新旧数据列表两个遍历可能不只一次
         * 
         * @param newList
         *          新数据,必须有序,且升序
         * @param oldList
         *          旧数据,必须有序,且升序
         * @return
         */
        public static <T extends Comparable<T>> Diff<T> difference(List<T> newList, List<T> oldList) {
            List<T> unionList = new ArrayList<T>();
            List<T> addedList = new ArrayList<T>(oldList);
            List<T> removedList = new ArrayList<T>(newList);
            innerDifference(newList, oldList, unionList, addedList, removedList);
            return new Diff<T>(unionList, addedList, removedList);
        }

        /**
         * 新旧数据列表两个遍历可能不只一次
         * 
         * @param cursorList
         *          新数据,必须有序,且升序
         * @param baseList
         *          旧数据,必须有序,且升序
         * @param unionList
         * @param addedList
         * @param removedList
         */
        public static <T extends Comparable<T>> void difference(List<T> cursorList, List<T> baseList, List<T> unionList,
                List<T> addedList, List<T> removedList) {
            addedList.addAll(cursorList);
            removedList.addAll(baseList);
            innerDifference(cursorList, baseList, unionList, addedList, removedList);
        }

    }

    public List diff(String aFilePath, String bFilePath, String resultFilePath) throws FileNotFoundException {
        BufferedReader aReader = null, bReader = null;
        String aLine, bLine;
        String delimiter = " ";
        try {
            aReader = new BufferedReader(new FileReader(aFilePath));
            bReader = new BufferedReader(new FileReader(aFilePath));
            if (null != (aLine = aReader.readLine())) {
            }
        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            closeQuietly(aReader);
            closeQuietly(bReader);
            closeQuietly(aReader);
        }
        return null;
    }

    public static <T extends Closeable> T closeQuietly(T c) {
        if (null != c) {
            try {
                c.close();
            } catch (IOException e) {
                // ALog.d("close", e.getMessage());
            }
        }
        return null;
    }
}

 

统计两组数据的交集和补集(新旧数据的差异比较算法)遍历一次

标签:

原文地址:http://www.cnblogs.com/Fang3s/p/4762715.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!