用DFS解决组合问题

一直以来,大量作各种管理系统的程序员,大量的时间都在处理各种增删改查问题,对于其余的方面尤为是算法层面的涉及较少,此次就遇到一个问题。前端

业务场景

用户上传一份Excel,让用户选择其中的部分列头,程序对列头作两两组合,并对全部的组合取Excel表中的数据,绘制一个折线图。java

问题分解

  1. 文件上传。前端使用异步插件提交文件,后台使用file接受便可。升级点在于进度条、重传、备份等
  2. 文件解析,基于POI、easyexcel等框架,都不难实现
  3. 选择列头作两两组合,典型的求组合问题,DFS的方式是通用实现方式。
  4. 组合获取数据,哈希表作key的方式,取出部分列,没难度
  5. 绘制图表,echarts、d3js、highcharts、G2 都没有太大难度

技术实现

抽象后的背景:针对两两组合,即在m列中求出全部2个的组合,能够经过双重循环完成,简单易懂。程序员

双重循环

for(int i=0;i<arr.length;i++){
      for(int j=i+1;j<arr.length;j++){
            //...do something
            arr[i]; arr[j];      
      }
}

通用作法,基于dfs算法实现算法

DFS深度便利

private void dfs(int[] arr, int target,int begin, Deque<Integer> path, Set<List<Integer>> res) {
     if ( path.size()== target) {
        res.add(new ArrayList<>(path));
        return;
    }else if(begin>arr.length){
        return;
    }
    for (int i = begin; i < arr.length; i++) {
        path.add(arr[i]);
        dfs(arr,target,i+1,path,res);
        path.removeLast();
    }
}

优劣比较

方式一快速简单,上手快,缺点是没有扩展性,一旦组合数变成三、四、5,多重循环显然不合适。
方式二通用能适用各类组合数变化,只要调整target的数字便可。echarts

后记

这是一个并不复杂的问题,但反映出算法在编码过程当中的一些问题,必定要注意抽象,将个性化的业务问题抽象为技术问题,用通用的技术去解决,代码的健壮性大大提升。框架

相关文章
相关标签/搜索