最近做个广告系统,其中有一功能是按数据权重(weight)来显示广告,所以一直没思路,想大家讨教一下,在线等哦。

解决方案 »

  1.   

    数据权重(weight)是个什么概念?设计一个数据库权重表吧
      

  2.   

    写一个简单的方法根据权重按照比例随机显示对应的广告。
    比如有个广告list,广告属性有id,weight,写个通用方法来根据权重显示广告id
    //本以为很容易,看来想错了,看代码:
      

  3.   


    public class TEST {    public static void main(String[] args) {
            List<Ad> list = new ArrayList<Ad>();
            list.add(new Ad(1,5));
            list.add(new Ad(2,10));
            list.add(new Ad(3,20));
            list.add(new Ad(4,30));
            list.add(new Ad(5,35));
            ComTest com = new ComTest();
            Collections.sort(list,com); //对list中广告的权重要先排序,否则无法将随机数顺序安置到对应的区间        int id1=0;
            int id2=0;
            int id3=0;
            int id4=0;
            int id5=0;
            for (int i = 0; i < 100; i++) {
                int id = getAd(list);
                if(id==1) id1++;
                if(id==2) id2++;
                if(id==3) id3++;
                if(id==4) id4++;
                if(id==5) id5++;
            }
            System.out.println("12345:"+id1+"|"+id2+"|"+id3+"|"+id4+"|"+id5);
        }
        public static int getAd(List<Ad> list){  //根据权重返回对应id的方法
            int sumWeight = 0; //得到总权重
            for(Ad ad :list){
                sumWeight+=ad.getWeight();
            }
            Random rand = new Random();
            int x = rand.nextInt(sumWeight) + 1; //生成随机数
            int start = 0; int end = 0;
            for(int i=1;i<list.size();i++){
                //计算各个权重对应的起止数值段
                if(i==1){
                    start = list.get(i-1).getWeight();
                    end = list.get(i-1).getWeight()+list.get(i).getWeight();
                }else{
                    start = end;
                    end = start+list.get(i).getWeight();
                }
                //根据随机数落入的范围返回对应几率的广告id
                if(x>start && x<=end){
                    return list.get(i).getId();
                }else if(x<=start){
                    return list.get(i-1).getId();
                }else{
                    continue;
                }
            }
            return 0;
        }
    }
            
    class Ad{
        
        public Ad(int id,int weight){
            this.id = id;
            this.weight = weight;
        }
        int id;
        int weight;
        
        public int getId() {
            return id;
        }
        
        public void setId(int id) {
            this.id = id;
        }
        
        public int getWeight() {
            return weight;
        }
        
        public void setWeight(int weight) {
            this.weight = weight;
        }
        
    }
      

  4.   

    为了根据权重排序list而实现的comparator:import java.util.Comparator;public class ComTest implements Comparator<Ad> {    public int compare(Ad o1, Ad o2) {
            if (o1.getWeight() < o2.getWeight()) {
                return -1;
            } else if (o1.getId() > o2.getId()) {
                return 1;
            } else {
                return 0;
            }
        }
    }
      

  5.   

    这句话是什么意思呢,能讲一下吗,好像就是为了这句话而写的啊
      Collections.sort(list,com); //对list中广告的权重要先排序,否则无法将随机数顺序安置到对应的区间
    但是这个可有可无啊,我注释了,照样运行通过。
      

  6.   

    这个必须要的,你要根据权重的大小对list排序。排序好后,对应的随机数才能正确的落在合适的范围内。
    比如有3个广告权重是1、5、10,那么为了保证按正确的比率显示广告(显示几率为:1/16 , 5/16, 10/16),产生的随机数在 1、2-6之间、7-16之间,分别显示id1/2/3的广告。如果不先对权重排序,那么对应start/end那段代码就无法正确的计算出上面这3个区间(比如权重未排序是10、5、1,那么区间就计算成了1-10,10-15,15-16)。==我想想,啊对,可以不用排序,产生的范围虽然不是顺序的,但区间大小是正确的,可以取消排序类!你再试试
      

  7.   

    谢谢marf_cn 的回答,我已经明白了,还是加上排序吧。想交你个朋友,可以吗,我QQ:837442656
      

  8.   

    还有就是如果我要是写代码的话,直接写 getAd(List<Ad> list)这个方法到action中就行了吧,至于权重,就是让客户端来设置,然后我从后台来获取参数