计算多个数字之间的唯一组合,非顺序组合 @杨章隐

  1. 最近在做公司的活动优惠系统,需求方提出了指定药品的需求,即每个药品随意组合,价格达到门槛了就可以使用优惠券
    举例:药品有 1、2、3,价格也为1、2、3
    那么组合就有1、12、123、13、2、23、3 价格分别为 1、3、6、4、2、5、3
    实现思路:每次先拿出数组集合中的第一个数字与其他数字进行配对组合并每次都记录下来得到结果。
    
  2. 总结:所以这个问题并非顺序组合的问题,而是一个组合积乘的问题,还有组合后的门槛比较问题。
  3. 组合算法代码实现(可以替换掉具体的实体对象)
    1. 算法实现
      public class Test007 {
          public static void main(String[] args) {
              List<DTO> list = new ArrayList<>();
              DTO dto = new DTO();
              dto.setId("1");
              dto.setPrice(1L);
              list.add(dto);
      
              dto = new DTO();
              dto.setId("2");
              dto.setPrice(2L);
              list.add(dto);
      
              dto = new DTO();
              dto.setId("3");
              dto.setPrice(3L);
              list.add(dto);
      
              dto = new DTO();
              dto.setId("7");
              dto.setPrice(3L);
              list.add(dto);
      
              dto = new DTO();
              dto.setId("9");
              dto.setPrice(3L);
              list.add(dto);
      
              List<Result> results = getCombination(list);
          }
      
          /**
           * 计算所有药品组合 以及组合价格
           * @param array
           * @return
           */
          public static List<Result> getCombination(List<DTO> array){
              List<Result> result = new ArrayList<>();
      
      
              int startNum = 0;
              int endNum = array.size();
              List<DTO> DTOS = new ArrayList<>();
              for(int i = startNum ; i < endNum; i ++){
                  DTOS.clear();
                  DTOS.add(array.get(i));
                  //传入节点结果 记录进结果
                  getResult(DTOS, result);
                  int tempI = i;
                  calculation(++ tempI, endNum, DTOS,   array, result);
              }
      
              return result;
          }
      
          /**
           * 计算首个药品与其他药品的组合
           * @param start
           * @param end
           * @param drugs
           * @param drugsArray
           * @param result
           */
          public static void calculation(int start, int end, List<DTO> drugs, List<DTO> drugsArray, List<Result> result){
              for(int i = start; i < end; i ++){
                  /粗糙解决数组内存地址一样的问题
                  List<DTO> dtos = new ArrayList<>();
                  for(DTO dto : drugs){
                      dtos.add(dto);
                  }
                  /粗糙解决数组内存地址一样的问题
                  dtos.add(drugsArray.get(i));
                  //传入节点结果 记录进结果
                  getResult(dtos, result);
                  int tempI = i;
                  calculation(++ tempI, end, dtos, drugsArray, result);
              }
          }
      
      
          /**
           * 处理结果 为返回结果赋值
           * @param drugs
           * @param results
           */
          public static void getResult(List<DTO> drugs, List<Result> results){
              Result result = new Result();
              List<Long> ids = new ArrayList<>();
              Long price = 0L;
              for(DTO dto : drugs){
                  ids.add(Long.parseLong(dto.getId()));
                  price += dto.getPrice();
              }
              result.setIds(ids.toString());
              result.setPrice(price);
              results.add(result);
          }
      }
      

    2. 实体类
      
      class DTO {
          String id;
          Long price;
      
          public String getId() {
              return id;
          }
      
          public void setId(String id) {
              this.id = id;
          }
      
          public Long getPrice() {
              return price;
          }
      
          public void setPrice(Long price) {
              this.price = price;
          }
      
      }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

杨章隐

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

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

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

打赏作者

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

抵扣说明:

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

余额充值