(JAVA)仿拼多多砍价算法

前言 

这个是我花49c币在csdn上下载的,稍微做了些修改,给大家分享一下。觉得还不错的点个赞吧。

先上执行完毕后的控制台输出截图:

(JAVA)仿拼多多砍价算法_第1张图片

package com.dq.utils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;


/**
 * 获取砍价的集合公共方法
 * 2018年6月4日 上午9:35:57
 * version 1.0
 *
 * @author lwf
 */
public class BargainCommonUtils {

    private static final Logger logger = LoggerFactory.getLogger(BargainCommonUtils.class);

    /**
     * 砍价算法优化,避免死循环和空指针
     * 
为避免价格生成出错,要求:count<=100;price/count>=0.08 *
2018年8月14日 上午9:54:39 *
version 1.0 *
@author lwf *
@param count *
@param price *
@param finalPrice *
@return */ public static List getBargainList(Integer count, BigDecimal price, BigDecimal finalPrice) { List list = new BargainCommonUtils().getTempBargainList(count, price, finalPrice); int i = 0; while (list == null || list.size() == 0 || list.size() != count) { list = new BargainCommonUtils().getTempBargainList(count, price, finalPrice); i++; if (i > 50000) { logger.info("砍价集合生成超时!请重试或重新设定价格/次数比例!"); break; } } return list; } /* * 获取砍价的价格集合 *
2018年6月7日 下午4:32:31 *
version 1.0 *
@author lwf */ public static List getTempBargainList(Integer count, BigDecimal price, BigDecimal finalPrice) { BigDecimal sourcePrice = price; sourcePrice = sourcePrice.subtract(finalPrice); // 实际要折扣掉的金额 sourcePrice = sourcePrice.setScale(2, RoundingMode.HALF_DOWN);// 把多余的小数点去掉 ArrayList tempPrices = new ArrayList<>();// 实际被砍掉的价格集合 Map lastPrice = new HashMap<>();// 最后一次的砍价剩余的价格 int sum = 0;// 实际砍价次数 ArrayList finalPrices = new ArrayList<>(); // 最终所需要的砍价集合 finalPrice = new BigDecimal(0); BigDecimal divisor = new BigDecimal(count); // 获取砍价的平均值 int countTmep = 2; getPirces(sourcePrice, countTmep, tempPrices, finalPrice, lastPrice); tempPrices.add(lastPrice.get("lastPrice")); sum = tempPrices.size(); if (sum > count) { // 如果实际砍价次数大于预期次数,则再进行处理 int temp = sum - count;// 相差次数 BigDecimal sumPrice = new BigDecimal(0.00); for (int i = 0; i < tempPrices.size(); i++) { if (i < tempPrices.size() - temp) { finalPrices.add(tempPrices.get(i)); } else { sumPrice = sumPrice.add(tempPrices.get(i)); // 多余的砍价 } } // 把多余的砍价平均分散到前count中的砍价 BigDecimal divide = null; try { divide = sumPrice.divide(new BigDecimal(count), 2, RoundingMode.HALF_DOWN); } catch (Exception e) { logger.warn(e.getMessage()); e.printStackTrace(); } divide = divide.setScale(2, RoundingMode.HALF_DOWN); for (int i = 0; i < finalPrices.size(); i++) { BigDecimal add = finalPrices.get(i).add(divide); finalPrices.set(i, add); } } else if (sum == count) { finalPrices = tempPrices; } else { return null; } // 价格矫正 补总差价,多减少增 BigDecimal totalPrice = new BigDecimal(0); for (BigDecimal bd : finalPrices) { totalPrice = bd.add(totalPrice); } logger.info("价格矫正前的totalPrice:" + totalPrice); // 如果集合中的总价大于实际原价,则把集合中任意一个大于这个差价的价格减去差价(误差都不会超过0.1) int inFlag = 0; if (totalPrice.compareTo(sourcePrice) > 0) { BigDecimal subtract = totalPrice.subtract(sourcePrice); for (int i = 0; i < finalPrices.size(); i++) { if (finalPrices.get(i).compareTo(subtract) > 0) { // 集合中的大于这个差价的价格 BigDecimal changedPrice = finalPrices.get(i).subtract(subtract); finalPrices.set(i, changedPrice); inFlag = 1; break; } } } if (totalPrice.compareTo(sourcePrice) < 0) { // 如果集合中的总价小于等于实际原价,则把集合中最后一个价格加上差价(误差都不会超过0.1) BigDecimal subtract = sourcePrice.subtract(totalPrice); BigDecimal sourceLastPrice = finalPrices.get(finalPrices.size() - 1); BigDecimal changedPrice = sourceLastPrice.add(subtract); finalPrices.set(finalPrices.size() - 1, changedPrice); inFlag = 1; } if (totalPrice.compareTo(sourcePrice) == 0) { inFlag = 1; } if (inFlag == 0) { // 如果没有价格大于这个差价,则再完整的调一次本方法 return null; } else { logger.info("sourcePrice:" + sourcePrice); logger.info("*********************************"); totalPrice = new BigDecimal(0); for (BigDecimal bd : finalPrices) { totalPrice = bd.add(totalPrice); } logger.info("预期砍价次数:" + count + " 实际砍价次数:" + finalPrices.size() + " 价格矫正后的totalPrice:" + totalPrice); logger.info(Arrays.toString(finalPrices.toArray())); return finalPrices; } } /** * 获取被砍的价格集合 *
2018年6月4日 下午3:19:07 *
version 1.0 *
@author lwf *
@param sourcePrice 原价 *
@param avgPrice 砍价平均值: 原价/砍价次数=砍价平均值 *
@param tempPrices 砍价价格集合 *
@param finalPrice 最终价 */ public static void getPirces(BigDecimal sourcePrice, int countTemp, List tempPrices, BigDecimal finalPrice, Map lastPrice) { Random r = new Random(); double d = sourcePrice.divide(new BigDecimal(++countTemp), 2, RoundingMode.HALF_DOWN).doubleValue(); if (tempPrices.size() > 0 && tempPrices.size() % 4 == 0) { countTemp = countTemp - 3; } Double randomPrice = r.nextDouble() * d + 0.01; // 例如:生成0到9.99之间的随机数 BigDecimal bargainPrice = new BigDecimal(randomPrice); // 被砍掉的价格 bargainPrice = bargainPrice.setScale(2, RoundingMode.HALF_DOWN); BigDecimal surplusPrice = sourcePrice.subtract(bargainPrice); // 剩余价格 if (surplusPrice.compareTo(finalPrice) <= 0) { return; } tempPrices.add(bargainPrice); lastPrice.put("lastPrice", surplusPrice); getPirces(surplusPrice, countTemp, tempPrices, finalPrice, lastPrice); } /* @Test public void testBargain() { int count = 100; BigDecimal price = new BigDecimal(7); BigDecimal finalPrice = new BigDecimal(0); List list = new BargainCommonServiceImpl().getTempBargainList(count, price, finalPrice); int i = 0; while(list==null || list.size()==0||list.size()!=count) { list = new BargainCommonServiceImpl().getTempBargainList(count, price, finalPrice); i ++; if(i>50000) { logger.info("砍价集合生成超时!请重试或重新设定价格/次数比例!"); System.out.println("砍价集合生成超时!请重试或重新设定价格/次数比例!"); break; } } System.out.println(i); }*/ public static void main(String[] args) { int count = 10; BigDecimal price = BigDecimal.valueOf(7L); BigDecimal finalPrice =BigDecimal.ZERO; List list = BargainCommonUtils.getTempBargainList(count, price, finalPrice); list.forEach(bigDecimal -> { System.out.printf(bigDecimal.toString()); }); } }

 

你可能感兴趣的:((JAVA)仿拼多多砍价算法)