zoukankan      html  css  js  c++  java
  • 年龄使用128位二进制字符串进行存储,这样进行分段枚举时就可以保证,能够快速灵活的标识每一段

    package test;
    
    import org.apache.commons.lang3.StringUtils;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * Created by zzq on 2020/11/27.
     */
    public class RangeProcessor {
        private Map<String, List<Range>> mediaAgeRangeMap;
    
        /**
         * 该构造函数期望应用首次启动调用
         * (非线程安全)
         *
         * @param rangeList
         */
        public RangeProcessor(List<Range> rangeList) {
            if (rangeList == null) {
                throw new RuntimeException("rangeList不能为空");
            }
            mediaAgeRangeMap = new HashMap<>();
            for (int i = 0; i < rangeList.size(); i++) {
                Range range = rangeList.get(i);
                range.initSegmentList();
                List<Long> segmentList = range.getSegmentList();
                if (segmentList == null || segmentList.size() == 0) {
                    throw new RuntimeException("Range对象segmentList属性不允许为空,请检查Range#getBinRangeStr返回值是否为二进制字符串");
                }
                String typeId = range.getTypeId();
                List<Range> innerRangeList = mediaAgeRangeMap.get(typeId);
                if (innerRangeList == null) {
                    innerRangeList = new ArrayList<>();
                    mediaAgeRangeMap.put(typeId, innerRangeList);
                }
                innerRangeList.add(range);
            }
        }
    
        /**
         * 根据媒体id以及输入的二进制字符串,获取范围标记列表,并升序排列
         * (腾讯专用)
         *
         * @param typeId
         * @param binAgeRangeStr
         * @param tencent
         * @return
         * @throws Exception
         */
        public List<String> getRangeTagList(String typeId, String binAgeRangeStr, boolean tencent) {
            checkBinAgeRange(binAgeRangeStr);
            if (tencent) {//处理腾讯逻辑
                int startIndex = -1;
                int endIndex = -1;
                for (int i = 0; i < binAgeRangeStr.length(); i++) {
                    char currChar = binAgeRangeStr.charAt(i);
                    if (startIndex == -1 && currChar == 49) {//起始位置
                        endIndex = startIndex = i;
                    }
                    if (startIndex != -1 && currChar == 48) {//开始索引位置标记后,以0为标识寻找结束位置
                        endIndex = i - 1;
                        break;
                    }
                }
                List<String> retRangeTagList = new ArrayList<>();
                retRangeTagList.add(startIndex + "");
                retRangeTagList.add(endIndex + "");
                return retRangeTagList;
            }
            return getRangeTagList(typeId, binAgeRangeStr);
        }
    
        /**
         * 根据媒体id以及输入的二进制字符串,获取范围标记列表,并升序排列
         *
         * @param typeId
         * @param binAgeRangeStr
         * @return
         */
        public List<String> getRangeTagList(String typeId, String binAgeRangeStr) {
            checkBinAgeRange(binAgeRangeStr);
            if (mediaAgeRangeMap == null) {
                throw new RuntimeException("未调用AgeRangeProcessor构造函数");
            }
            List<Range> rangeList = mediaAgeRangeMap.get(typeId);
            if (rangeList == null) {
                throw new RuntimeException("找不到typeId标识的区间,或未调用RangeProcessor构造函数");
            }
            List<String> retAgeRangeNoList = new ArrayList<>();
            for (int i = 0; i < rangeList.size(); i++) {
                Range range = rangeList.get(i);
                if (range.getBinRangeStr() == null || range.getBinRangeStr().length() != binAgeRangeStr.length()) {
                    throw new RuntimeException("传入的二进制字符串长度,与初始化的对比字符串长度不同;或初始化字符串为空,Range#getBinRangeStr方法不允许返回空");
                }
                if (segmentCheck(range, binAgeRangeStr)) {
                    retAgeRangeNoList.add(range.getRangeTag());
                }
            }
            return retAgeRangeNoList;
        }
    
        private boolean segmentCheck(Range range, String binAgeRangeStr) {
            List<Long> segmentList = range.getSegmentList();
            List<Long> inputSegmentList = createSegment(binAgeRangeStr);
            for (int i = 0; i < segmentList.size(); i++) {
                Long segmentBin = segmentList.get(i);
                Long inputSegmentBin = inputSegmentList.get(i);
                if ((segmentBin & inputSegmentBin) != segmentBin) {
                    return false;
                }
            }
            return true;
        }
    
        static List<Long> createSegment(String binAgeRangeStr) {
            int length = binAgeRangeStr.length();
            int segmentNum = length >> 5;
            List<Long> segmentList = new ArrayList<>();
            int start = 0;
            for (int i = 0; i < segmentNum; i++) {
                int end = start + 32;
                addSegmentRadix2Long(binAgeRangeStr, segmentList, start, end);
                start = end;
            }
            if (start < length) {
                addSegmentRadix2Long(binAgeRangeStr, segmentList, start, length);
            }
            return segmentList;
        }
    
        private static void addSegmentRadix2Long(String binAgeRangeStr, List<Long> segmentList, int start, int end) {
            String segmentStr = binAgeRangeStr.substring(start, end);
            segmentList.add(Long.parseLong(segmentStr, 2));
        }
    
        /**
         * 不是数字,或者字符串为空,则直接返回
         *
         * @param binAgeRange
         * @throws RuntimeException
         */
        static void checkBinAgeRange(String binAgeRange) {
            if (StringUtils.isBlank(binAgeRange) ||
                    !StringUtils.isNumeric(binAgeRange)) {
                throw new RuntimeException("输入的二进制字符串不能为空,且格式为数字");
            }
        }
    }
    package test;
    
    import java.util.List;
    
    /**
     * Created by zzq on 2020/11/27.
     */
    public abstract class Range {
        String typeId;//分类Id
        String rangeTag;//范围记号
        private List<Long> segmentList;
    
        public List<Long> getSegmentList() {
            return segmentList;
        }
    
        public String getTypeId() {
            return typeId;
        }
    
        public void setTypeId(String typeId) {
            this.typeId = typeId;
        }
    
        public String getRangeTag() {
            return rangeTag;
        }
    
        public void setRangeTag(String rangeTag) {
            this.rangeTag = rangeTag;
        }
    
        abstract String getBinRangeStr();//需要设置binRangeStr二进制字符串
    
        void initSegmentList() {
            String binRangeStr = getBinRangeStr();
            RangeProcessor.checkBinAgeRange(binRangeStr);
            segmentList = RangeProcessor.createSegment(binRangeStr);
        }
    }
    package test;
    
    import lombok.Data;
    
    /**
     * Created by zzq on 2020/11/27.
     */
    @Data
    public class MediaAgeRange extends Range {
        int startAge;
        int endAge;
    
        @Override
        String getBinRangeStr() {
            char ageRange[] = new char[128];
            for (int i = 0; i < 128; i++) {
                if (i >= startAge && i <= endAge)
                    ageRange[i] = 49;
                else
                    ageRange[i] = 48;
            }
            return String.valueOf(ageRange);
        }
    }
    package test;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Created by zzq on 2020/11/27.
     */
    public class Test {
        public static void main(String[] args) throws Exception {
            List<Range> mediaAgeRangeList = new ArrayList<>();
    ///*
            //18岁以下
            MediaAgeRange mediaAgeRange = new MediaAgeRange();
    //        mediaAgeRange.setBinAgeRange("01111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
            mediaAgeRange.setStartAge(1);
            mediaAgeRange.setEndAge(17);
            mediaAgeRange.setRangeTag("1");
            mediaAgeRange.setTypeId("baidu");
            mediaAgeRangeList.add(mediaAgeRange);
            //18-24岁
            MediaAgeRange mediaAgeRange1 = new MediaAgeRange();
    //        mediaAgeRange1.setBinAgeRange("00000000000000000011111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
            mediaAgeRange1.setStartAge(18);
            mediaAgeRange1.setEndAge(24);
            mediaAgeRange1.setRangeTag("2");
            mediaAgeRange1.setTypeId("baidu");
            mediaAgeRangeList.add(mediaAgeRange1);
            //25-34岁
            MediaAgeRange mediaAgeRange2 = new MediaAgeRange();
    //        mediaAgeRange2.setBinAgeRange("00000000000000000000000001111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
            mediaAgeRange2.setStartAge(25);
            mediaAgeRange2.setEndAge(34);
            mediaAgeRange2.setRangeTag("3");
            mediaAgeRange2.setTypeId("baidu");
            mediaAgeRangeList.add(mediaAgeRange2);
            //35-44岁
            MediaAgeRange mediaAgeRange3 = new MediaAgeRange();
    //        mediaAgeRange3.setBinAgeRange("00000000000000000000000000000000000111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000");
            mediaAgeRange3.setStartAge(35);
            mediaAgeRange3.setEndAge(44);
            mediaAgeRange3.setRangeTag("4");
            mediaAgeRange3.setTypeId("baidu");
            mediaAgeRangeList.add(mediaAgeRange3);
            //44岁以上
            MediaAgeRange mediaAgeRange4 = new MediaAgeRange();
    //        mediaAgeRange4.setBinAgeRange("00000000000000000000000000000000000000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
    //        mediaAgeRange4.setBinAgeRange("00000000000000000000000000000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111");
            mediaAgeRange4.setStartAge(45);
            mediaAgeRange4.setEndAge(127);
            mediaAgeRange4.setRangeTag("5");
            mediaAgeRange4.setTypeId("baidu");
            mediaAgeRangeList.add(mediaAgeRange4);
    
    //*/
            RangeProcessor rangeProcessor = new RangeProcessor(mediaAgeRangeList);
            String abc = "00000000000000000011111111111111111000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111";
            String uu = "00000000000000111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000000";
            List<String> ret = rangeProcessor.getRangeTagList("baidu", abc);
            List<String> re1t = rangeProcessor.getRangeTagList("baidu", uu, true);
    
    
            System.out.println();
        }
    
    }
  • 相关阅读:
    poj 2391 Ombrophobic Bovines
    混合欧拉回路poj 1637 Sightseeing tour
    POJ1149-PIGS
    C
    B
    A
    C
    B
    A
    O
  • 原文地址:https://www.cnblogs.com/zzq-include/p/14052249.html
Copyright © 2011-2022 走看看