设计一个根据能自动计算出依赖关系链的编译系统

注:这个问题是在一次面试的时候遇到的,当时还以为就是简单的maven打包设置,然后面试官说是要设计一个类似maven能自动设别的编译系统。这里说下思路及实现过程。

首先,这个问题说简单也简单,说复杂也复杂;简单的说,那就是直接让客户把这种依赖关系定义好,那我们就不用那么辛苦了,当然这是理想的状态,实际上很多客户很"懒"的,他可能只告诉你哪两个项目之间有依赖关系,他不可能把所有依赖关系链都告诉你:A依赖B,B依赖C,A依赖D,D依赖F。。。。但是需要你通过算法来计算出来得到诸如:A-B-C、A-D-F的依赖链,而且还要保证你得到的依赖链不得有重复情况。

好了,话不多说,直接看代码把:

package com.cn.lizihao.compileTool;
import java.util.*;
public class CompileTools2 {
    //模拟数据,假设现在知道单个依赖、两两依赖,实际我们会有项目名称,根据项目名称的两两或者单一依赖进行检索、配对、组合
    public static List<List<String>> getDatas(){
        List<List<String>> datas = new ArrayList<>();
        List<String> a = new ArrayList<>(Arrays.asList(new String[]{"a","b"}));
        List<String> b = new ArrayList<>(Arrays.asList(new String[]{"b","c"}));
        List<String> c = new ArrayList<>(Arrays.asList(new String[]{"e","g"}));
        List<String> d = new ArrayList<>(Arrays.asList(new String[]{"a","c"}));
        List<String> e = new ArrayList<>(Arrays.asList(new String[]{"e","b"}));
        List<String> f = new ArrayList<>(Arrays.asList(new String[]{"b","g"}));
        List<String> g = new ArrayList<>(Arrays.asList(new String[]{"c","d"}));
        datas.add(a);
        datas.add(b);
        datas.add(c);
        datas.add(d);
        datas.add(e);
        datas.add(f);
        datas.add(g);
        return datas;
    }
    //采用集合保存依赖关系   采用冒泡法+递归重复计算、组合集合
    public static void reSetDatas(List<List<String>> datas,List<List<String>> finalList,int count){
        List<List<String>> compareList = finalList;
        if(finalList == null || finalList.size()==0){//如果是第一次,则集合自己比较
            compareList.addAll(datas);
        }
        for(int i=0;i<datas.size() && count < datas.size();i++){
            List<String> a =  datas.get(i);
            //获取首末元素
            String s1 = a.get(0);
            String s2 = a.get(a.size() - 1);
            if (convertData(finalList,a)) continue;
            for(int j = 0;j < compareList.size();j++){
                List<String> convertList = new ArrayList<>();
                List<String> b =  compareList.get(j);
                if (convertData(finalList,b)) continue;
                //获取首末元素
                String s3 = b.get(0);
                String s4 = b.get(b.size() - 1);
                if(s1.equals(s4) && !s2.equals(s3)){
                    convertList.addAll(b);
                    convertList.addAll(a);
                    finalList.add(distinctList(convertList));
                }
                if(s2.equals(s3) && !s1.equals(s4)){
                    convertList.addAll(a);
                    convertList.addAll(b);
                    finalList.add(distinctList(convertList));
                }
            }
            count++;
            reSetDatas(datas,finalList,count);
        }
    }
//当集合中只有一个元素且不存在依赖关系并且未添加过时,进行添加
    private static boolean convertData(List<List<String>> finalList,List<String> a) {
        if (a == null || a.size() <= 0) return true;
        if (a.size() == 1) {
            if (!finalList.contains(a))
                finalList.add(a);
            return true;
        }
        return false;
    }
    //对最终组合完成的集合进行去重、过滤包含链接
    public static List<List<String>> filterList(List<List<String>> list){
        if(list == null || list.size() == 0) return null;
        List<List<String>> result = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            List<String> list1 = list.get(i);
            boolean a = true;
            for (int j = i+1; j < list.size() && a; j++) {
                List<String> list2 = list.get(j);
                boolean isContain = compareList(list1, list2);
                if(isContain){
                    a = false;
                    list.remove(i);
                    i--;//注:这里因为将下标去除了,指针后移,所以需要做--操作
                    continue;
                }
            }
            if(a) result.add(list1);
        }
        return result;
    }
    //比较两个集合中元素如果存在包含关系则返回true,否则false
    public static boolean compareList(List<String> list1,List<String> list2){
        if(list1==null || list1.size()==0 || list2 ==null || list2.size()==0) return true;
        boolean result = true;
        for (int i = 0; i <list1.size() ; i++) {
            if(!list2.contains(list1.get(i))) result = false;
        }
        return result;
    }

    //对单个集合去重
    public static List<String> distinctList(List<String> list){
        if(list == null || list.size()==0) return null;
        List<String> newList = new ArrayList<>();
        for (int i = 0; i <list.size() ; i++) {
            if(!newList.contains(list.get(i))) newList.add(list.get(i));
        }
        return newList;
    }

    public static void main(String[] args) {
        List<List<String>> datas = getDatas();
        System.out.println(datas);
        List<List<String>> finalList = new ArrayList<>();
        int count = 0;
        reSetDatas(datas,finalList,count);
//        System.out.println(finalList);
        List<List<String>> lists = filterList(finalList);
        System.out.println(lists);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

远方的、远方的、、、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值