砍价算法,随机金额砍价代码,可以参考一下

随机金额砍价代码,可以参考一下

第一个Java文件:
砍价功能代码及实体类测试代码

package com.component.test.controller;

import com.component.test.javacommon.util.GsonUtil;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 2 * @Author: dengjunbao
 * 3 * @Date: 2019/9/6 17:11
 * 4
 */
public class Bargain {
    /**
     * 1.总金额不超过总共可砍的价格*100  单位是分
     * 2.每次砍价都能砍到金额,最低不能低于1分,最大金额不能超过(总共可砍的价)*100
     */
    private static final int MINMONEY = 1;
    private static final int MAXMONEY = 10 * 100;

    /**
     * 这里为了避免某一次砍价占用大量资金,设定非最后一次砍价的最大金额,
     * 把他设置为砍价金额平均值的N倍
     */
    private static final double TIMES = 3.1;

    /**
     * 砍价合法性校验
     * 控制金额过小或者过大
     */
    private static boolean isRight(int money, int surplusKnife) {
        double avg = money / surplusKnife;
        //小于最小金额
        if (avg < MINMONEY) {
            return false;
        } else if (avg > MAXMONEY) {
            return false;
        }
        return true;
    }

    /**
     * 随机分配一个金额
     *
     * @param money:砍价金额
     * @param minS:最小金额
     * @param maxS:最大金额
     * @param surplusKnife
     * @return
     */
    private static int randomReducePrice(int money, int minS, int maxS, int surplusKnife) {
        //若只剩一次,则直接返回
        if (surplusKnife == 1) {
            return money;
        }
        //如果最大金额和最小金额相等,直接返回金额
        if (minS == maxS) {
            return minS;
        }
        int max = maxS > money ? money : maxS;
        //分配砍价正确情况,允许砍价的最大值
        int maxY = money - (surplusKnife - 1) * minS;
        //分配砍价正确情况,允许砍价最小值
        int minY = money - (surplusKnife - 1) * maxS;
        //随机产生砍价的最小值
        int min = minS > minY ? minS : minY;
        //随机产生砍价的最大值
        max = max > maxY ? maxY : max;
        //随机产生一个砍价
        return (int) Math.rint(Math.random() * (max - min) + min);
    }

    /**
     * 砍价----返回一个随机金额
     *
     * @param money 待砍总价
     * @param surplusKnife 待砍刀数
     * @return
     */
    private static int splitReducePrice(int money, int surplusKnife) {
        //金额合法性分析
        if (!isRight(money, surplusKnife)) {
            return 0;
        }
        //每次砍价的最大的金额为平均金额的TIMES倍
        int max = (int) (money * TIMES / surplusKnife);
        max = max > MAXMONEY ? MAXMONEY : max;
        int one = randomReducePrice(money, MINMONEY, max, surplusKnife);
        return one;
    }

    /**
     获取区间内的一个随机整数
     原理:要得到的随机数的范围是[110,130],返回的伪随机数的范围是[0,130),
     也即[0,130-1];对得到的这个数模长度是129,于是得到的数的范围是[0,129];
     将得到的随机数取余,控制最大值为区间的差数[max-min],这样就可以得到一个区间差数内的一个随机数[min-min,max-min],
     再把这个随机数加上最小值,就可以得出[min,max]区间内的一个随机数
     */
    private static int getRandom(int min, int max){
        Random random = new Random();
        int r = random.nextInt(max) % (max - min + 1) + min;
        return r;
    }

    /**
     * 该方法用于用户砍价开始时初始化砍价配置
     * @param needMoney 待砍总价
     * @param minKnife 最少需要砍价刀数
     * @param maxKnife 最多需要砍价刀数
     * */
    private static String getBargainConfig(int needMoney, int minKnife, int maxKnife, HdUser hdUser) {
        try {
            //获取随机总刀数
            int knifeNum = getRandom(minKnife,maxKnife);
            System.out.println("随机刀数:"+knifeNum);
            Map bargainRecordMap = new HashMap();
            bargainRecordMap.put("needMoney",needMoney + "");
            bargainRecordMap.put("knifeNum",knifeNum + "");
            bargainRecordMap.put("surplusMoney",needMoney + "");
            bargainRecordMap.put("surplusKnife",knifeNum + "");

            hdUser.setRemark(GsonUtil.toJson(bargainRecordMap));
        }catch (Exception e){
            return "102";
        }
        return "00";
    }

    /**
     * 预砍价----获取一个随机金额
     * @param surplusMoney 当前待砍金额
     * @param surplusKnife 当前待砍刀数
     * */
    private static int bargain(int surplusMoney, int surplusKnife) {
        //预算这次砍掉的钱
        int bargainMoney = 0;
        try {
            bargainMoney = splitReducePrice(surplusMoney, surplusKnife);
            if (surplusMoney < bargainMoney){
                bargainMoney = surplusMoney;
            }
            return bargainMoney;
        }catch (Exception e){
            e.printStackTrace();
            return -1;
        }
    }

    public static void main(String[] args) {
        int needMoney = 3800;
        int minKnife = 110;
        int maxKnife = 130;
        HdUser hdUser = new HdUser("xiaoming","");
        String sul = getBargainConfig(needMoney, minKnife, maxKnife, hdUser);
        if (!"00".equals(sul)){
            System.out.println("系统异常");
        }
        String remark = hdUser.getRemark();
        Map remarkMap = GsonUtil.fromJson(remark, Map.class);
        int knifeNum = Integer.parseInt(remarkMap.get("knifeNum"));
        int surplusMoney = Integer.parseInt(remarkMap.get("surplusMoney"));
        int surplusKnife = Integer.parseInt(remarkMap.get("surplusKnife"));
        int count1 = 0;
        int count2 = 0;
        for (int i = 0;i < knifeNum;i++){
            int res =  bargain(surplusMoney,surplusKnife);
            if(0 > res){
                System.out.println("系统异常");
            }
            surplusMoney -= res;
            surplusKnife --;

            count1 += res;
            count2 ++;

            System.out.println("砍掉"+(double)res/100+"元"+"剩余"+surplusMoney+"元"+"剩余"+(double)surplusKnife/100+"刀");

            remarkMap.put("surplusMoney",surplusMoney + "");
            remarkMap.put("surplusKnife",surplusKnife + "");
            hdUser.setRemark(GsonUtil.toJson(remarkMap));
        }
        System.out.println("总共砍了"+(double)count1/100+"元-----"+"总共砍了"+count2+"刀");
    }
}

class HdUser{
    String name = null;
    String remark = null;

    public HdUser(String name,String remark){
        this.name = name;
        this.remark = remark;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }
}

第二个java文件:
以下为工具类代码,需要导入google的包

package com.component.test.javacommon.util;

import com.google.gson.*;
import com.google.gson.annotations.SerializedName;
import com.google.gson.annotations.Since;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;

import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

public class GsonUtil {
	
	protected final static Log log = LogFactory.getLog(GsonUtil.class);
	
	/** 空的数据 "{}"。 */
    public static final String EMPTY_JSON = "{}";
    /** 空的数组(集合)数据 - {"[]"}。 */
    public static final String EMPTY_JSON_ARRAY = "[]";
    /** 默认的日期/时间字段的格式化模式。 */
    public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";
	
    public GsonUtil(){
    	super();
    }
    
    /**
     * 将target对象转换为json格式字符串
     * @param target						要转换的对象
     * @param targetType					对象的类型
     * @param isSerializeNulls				是否转换空对象(如 : String a = null; isSerializeNulls==true 则转换为 {a:null} ,否则转换为{})
     * @param version						配合@Since(Double)注解使用
     * 										(如:@Since(2.0) String a = "x";@Since(1.0) String b = "y";version==null 则注解不生效;
     * 										如version!=null,则只有@Since<=version的字段才会被转换,如version>=2.0,则转换为{a:"x",b:"y"},version=1.0,则转换为{b:"y"})
     * @param datePattern					设置Date时间格式转换为json数据的格式,默认"yyyy-MM-dd HH:mm:ss";
     * @param excludesFieldsWithoutExpose	是否只转换@Expose注解的字段,默认false;(如果excludesFieldsWithoutExpose=true,则只有带@Expose注解的字段才会被转换)
     * @param adaptTimestamp				使用Timestamp时间适配器转换Timestamp格式为json字符串
     * @return
     */
    public static String toJson(Object target, Type targetType, boolean isSerializeNulls, Double version,
            String datePattern, boolean excludesFieldsWithoutExpose,boolean adaptTimestamp) {
        if (target == null) return EMPTY_JSON;
        GsonBuilder builder = new GsonBuilder();
        if (isSerializeNulls) builder.serializeNulls();
        if (version != null) builder.setVersion(version.doubleValue());
        if (!StringUtils.hasText(datePattern)) datePattern = DEFAULT_DATE_PATTERN;
        if(adaptTimestamp){
        	TimestampTypeAdapter tt=new TimestampTypeAdapter(datePattern);
        	builder.registerTypeAdapter(Timestamp.class, tt);
        }else builder.setDateFormat(datePattern);
        if (excludesFieldsWithoutExpose) builder.excludeFieldsWithoutExposeAnnotation();
        return toJson(target, targetType, builder);
    }

    /**
     * 将target对象转换为json格式字符串
     * @param target	要转换的对象
     * @return
     */
    public static String toJson(Object target) {
        return toJson(target, null, false, null, null, false, true);
    }
    
    /**
     * 将target对象转换为json格式字符串(包括空值字段)
     * @param target	要转换的对象
     * @return
     */
    public static String toJsonWithNull(Object target) {
        return toJson(target, null, true, null, null, false, true);
    }

    /**
     * 将target对象转换为json格式字符串
     * @param target		要转换的对象
     * @param datePattern	设置Date时间格式转换为json数据的格式,默认"yyyy-MM-dd HH:mm:ss";
     * @return
     */
    public static String toJson(Object target, String datePattern) {
        return toJson(target, null, false, null, datePattern, false, true);
    }
    
    /**
     * 将target对象转换为json格式字符串
     * @param target			要转换的对象
     * @param datePattern		设置Date时间格式转换为json数据的格式,默认"yyyy-MM-dd HH:mm:ss";
     * @param adaptTimestamp	使用Timestamp时间适配器转换Timestamp格式为json字符串
     * @return
     */
    public static String toJson(Object target, String datePattern,boolean adaptTimestamp) {
        return toJson(target, null, false, null, datePattern, false, adaptTimestamp);
    }
    
    /**
     * 将target对象转换为json格式字符串
     * @param target	要转换的对象
     * @param version	配合@Since(Double)注解使用
     * 					(如:@Since(2.0) String a = "x";@Since(1.0) String b = "y";version==null 则注解不生效;
     * @return
     */
    public static String toJson(Object target, Double version) {
        return toJson(target, null, false, version, null, false, true);
    }
    
    /**
     * 将target对象转换为json格式字符串
     * @param target						要转换的对象
     * @param excludesFieldsWithoutExpose	是否只转换@Expose注解的字段,默认false;(如果excludesFieldsWithoutExpose=true,则只有带@Expose注解的字段才会被转换)
     * @return
     */
    public static String toJson(Object target, boolean excludesFieldsWithoutExpose) {
        return toJson(target, null, false, null, null, excludesFieldsWithoutExpose, true);
    }
    
    /**
     * 将target对象转换为json格式字符串
     * @param target						要转换的对象
     * @param version						配合@Since(Double)注解使用
     * 										(如:@Since(2.0) String a = "x";@Since(1.0) String b = "y";version==null 则注解不生效;
     * @param excludesFieldsWithoutExpose	是否只转换@Expose注解的字段,默认false;(如果excludesFieldsWithoutExpose=true,则只有带@Expose注解的字段才会被转换)
     * @return
     */
    public static String toJson(Object target, Double version, boolean excludesFieldsWithoutExpose) {
        return toJson(target, null, false, version, null, excludesFieldsWithoutExpose, true);
    }
    
    /**
     * 将target对象转换为json格式字符串
     * @param target		要转换的对象
     * @param targetType	对象的类型
     * @return
     */
    public static String toJson(Object target, Type targetType) {
        return toJson(target, targetType, false, null, null, false, true);
    }
    
    /**
     * 将target对象转换为json格式字符串
     * @param target		要转换的对象
     * @param targetType	对象的类型
     * @param version		配合@Since(Double)注解使用
     * 						(如:@Since(2.0) String a = "x";@Since(1.0) String b = "y";version==null 则注解不生效;
     * @return
     */
    public static String toJson(Object target, Type targetType, Double version) {
        return toJson(target, targetType, false, version, null, false, true);
    }
    
    /**
     * 将target对象转换为json格式字符串
     * @param target						要转换的对象
     * @param targetType					对象的类型
     * @param excludesFieldsWithoutExpose	是否只转换@Expose注解的字段,默认false;(如果excludesFieldsWithoutExpose=true,则只有带@Expose注解的字段才会被转换)
     * @return
     */
    public static String toJson(Object target, Type targetType, boolean excludesFieldsWithoutExpose) {
        return toJson(target, targetType, false, null, null, excludesFieldsWithoutExpose, true);
    }
    
    /**
     * 将target对象转换为json格式字符串
     * @param target						要转换的对象
     * @param targetType					对象的类型
     * @param version						配合@Since(Double)注解使用
     * 										(如:@Since(2.0) String a = "x";@Since(1.0) String b = "y";version==null 则注解不生效;
     * @param excludesFieldsWithoutExpose	是否只转换@Expose注解的字段,默认false;(如果excludesFieldsWithoutExpose=true,则只有带@Expose注解的字段才会被转换)
     * @return
     */
    public static String toJson(Object target, Type targetType, Double version, boolean excludesFieldsWithoutExpose) {
        return toJson(target, targetType, false, version, null, excludesFieldsWithoutExpose, true);
    }
    
    /**
     * 将json字符串转换为对象
     * @param json			json格式字符串
     * @param token			T类型封装器
     * @param datePattern	设置json数据的格式转换为Date时间格式,默认"yyyy-MM-dd HH:mm:ss";
     * @return
     */
    public static  T fromJson(String json, TypeToken token, String datePattern) {
        if (!StringUtils.hasText(json)) {
            return null;
        }
        GsonBuilder builder = new GsonBuilder();
        if (!StringUtils.hasText(datePattern)) {
            datePattern = DEFAULT_DATE_PATTERN;
        }
        Gson gson = builder.create();
        try {
            return (T)gson.fromJson(json, token.getType());
        } catch (Exception ex) {
            log.error(json + " 无法转换为 " + token.getRawType().getName() + " 对象!", ex);
            return null;
        }
    }
    
    /**
     * 将json字符串转换为对象
     * @param json	json格式字符串
     * @param token	T类型封装器
     * @return
     */
    public static  T fromJson(String json, TypeToken token) {
        return fromJson(json, token, null);
    }
    
    /**
     * 将json字符串转换为对象
     * @param json	json格式字符串
     * @param type	T类型封装器
     * @return
     */
    public static  T fromJson(String json, Type type) {
    	Gson gson = new Gson();
        return  (T)gson.fromJson(json, (Type) type);
    }
    /**
     * 将json字符串转换为clazz类型对象
     * @param json			json格式字符串
     * @param clazz			转换后的目标类型
     * @param datePattern	设置json数据的格式转换为Date时间格式,默认"yyyy-MM-dd HH:mm:ss";
     * @return
     */
    public static  T fromJson(String json, Class clazz, String datePattern) {
        if (!StringUtils.hasText(json)) {
            return null;
        }
        GsonBuilder builder = new GsonBuilder();
        if (!StringUtils.hasText(datePattern)) {
            datePattern = DEFAULT_DATE_PATTERN;
        }
        Gson gson = builder.create();
        try {
            return gson.fromJson(json, clazz);
        } catch (Exception ex) {
            log.error(json + " 无法转换为 " + clazz.getName() + " 对象!", ex);
            return null;
        }
    }
    
    /**
     * 将json字符串转换为clazz类型对象
     * @param json	json格式字符串
     * @param clazz	转换后的目标类型
     * @return
     */
    public static  T fromJson(String json, Class clazz) {
        return fromJson(json, clazz, null);
    }
    
    /**
     * 将target对象转换为json格式字符串
     * @param target		要转换的对象
     * @param targetType	对象的类型
     * @param builder		Gson实例构造器
     * @return
     */
    public static String toJson(Object target, Type targetType, GsonBuilder builder) {
        if (target == null) return EMPTY_JSON;
        Gson gson = null;
        if (builder == null) {
            gson = new Gson();
        } else {
            gson = builder.create();
        }
        String result = EMPTY_JSON;
        try {
            if (targetType == null) {
                result = gson.toJson(target);
            } else {
                result = gson.toJson(target, targetType);
            }
        } catch (Exception ex) {
            log.warn("目标对象 " + target.getClass().getName() + " 转换 JSON 字符串时,发生异常!", ex);
            if (target instanceof Collection || target instanceof Iterator || target instanceof Enumeration
                    || target.getClass().isArray()) {
                result = EMPTY_JSON_ARRAY;
            }
        }
        return result;
    }
    
	public static void main(String[] args) {
		Properties tp = new Properties();
		tp.put("a", "aa");
		tp.put("b", "bb");
		String json = GsonUtil.toJson(tp.entrySet());
		System.out.println(json);
	}
}

class SomeObject {
	@SerializedName("custom_naming")
	private final String someField;
	@Since(1.0)
	private final String someOtherField;
	@Since(2.0)
	private final int intFiled;

	public SomeObject(String a, String b, int c) {
		this.someField = a;
		this.someOtherField = b;
		this.intFiled = c;
	}
}

/**
 * timestamp时间类型适配器
 * @author lizhiwei
 *
 */
class TimestampTypeAdapter implements JsonSerializer, JsonDeserializer{
    private DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public TimestampTypeAdapter(String pattern){
    	format=new SimpleDateFormat(pattern);
    }
    public TimestampTypeAdapter(){}

    @Override
	public JsonElement serialize(Timestamp src, Type arg1, JsonSerializationContext arg2) {
    	if(src==null)return null;
        String dateFormatAsString = format.format(new Date(src.getTime()));
        return new JsonPrimitive(dateFormatAsString);
    }

    @Override
	public Timestamp deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
    	if(json==null)return null;
        if (!(json instanceof JsonPrimitive)) {
            throw new JsonParseException("数据有误!");
        }
        try {
            Date date = format.parse(json.getAsString());
            return new Timestamp(date.getTime());
        } catch (java.text.ParseException e) {
			// TODO Auto-generated catch block
        	GsonUtil.log.error(e.getMessage(), e);
			return null;
		}
    }
  
}

你可能感兴趣的:(java,Birber,砍价)