“中兴捧月”杯校园赛事嘉年华程序设计大赛题01

数字化婚姻配对尝试:建立一个模型,来模拟推导社会男女择偶过程。

1、100个男方,顺序,轮流从0号到99号女方中挑选自己最满意的一 位,然后向她发出配对邀请。
2、接受邀请最多的女方开始行动,对这些邀请的男性中,选择最满意 的一位。
3、那么这两位配对成功,剔除出样本,剩下的99对继续这样配对。
4、循环该配对法则,直到最后一对男女配对成功。

思路:
  1. 先确定存储的数据类型:可以确定的一点该题对数据的遍历远远大于修改(要一遍遍去匹配),故对于原始数据的存储用ArrayList(底层数据结构为数组)。
  2. 建立Person类:结合题目以及给的文件可以确定有七个属性,分别为ID, 样貌,品格,财富 , 期望样貌,期望品格,期望财富。主角样本的id为性别另外区别。
  3. 读取并存储:从给的文件来看,一行一行读取并写入到集合当中去。从题目要求看每次选出对象后主角要移除,原本数据要恢复。所以要另外创立两个集合来存储原始数据。
  4. 算法分析:
    1).从主角样本中拿到主角,并根据id加入到对应的样本中去
    2).男生开始根据自己的要求选择一位女生(可以是任何女士,但只能选择一位)。若两位女生得分相同,则看女生的样貌,品格,财富总值谁高选谁;在男生选女生的同时统计有哪些女生被选过且有多少男生选择她。
    3).统计哪位女生被男生选择的次数最多(即为最受欢迎的女生)。
    4).最受欢迎的女生在选择自己的男生里选择一位男生。选择标准:得分最高(若分数一样则看前三项加起来的值,若值还一样则比较id,选id较小的)
    5).若择偶成功的一对里面包含主角则匹配成功,然后从样本中剔除主角,原本数据恢复。反之,在男女集合中剔除这两个人,继续上面的步骤直到长度最小的集合
  5. 把主角一个个拿去匹配并打印出结果。

具体实现:

Person实现类:
package com.tulun.people;

import lombok.*;
/**
 * @author:liguozheng
 * @Date:2018/10/24
 * @time:17:01
 * @description:
 */
@NoArgsConstructor 
@AllArgsConstructor
@Setter
@Getter
@ToString
public class Person {

    private int id;        //ID
    private int appearance ;  //样貌
    private int treasure ;    //品格
    private int character ;   //财富
    private int appearanceLook;   //样貌期望
    private int treasureLook;     // 品格期望
    private int characterLook;    //财富期望
    
}
工具类Run:
package com.tulun.main;

import com.tulun.people.Person;
import java.io.*;
import java.util.*;

/**
 * @author:liguozheng
 * @Date:2018/10/24
 * @time:21:46
 * @description:
 */

@SuppressWarnings("all")
public class Run {

    private ArrayList maleList;
    private ArrayList femaleList;
    private ArrayList playersList;
    private ArrayList man ;
    private ArrayList mon ;
    int id;

    public Run(String malePath,String femalePath,String playersPath) throws IOException {

        this.mon = new ArrayList();
        this.man = new ArrayList();
        this.maleList = new ArrayList();
        this.femaleList = new ArrayList();
        this.playersList = new ArrayList();

        this.mon.addAll(saveCount(femalePath));
        this.man.addAll(saveCount(malePath));
        this.playersList.addAll(saveCount(playersPath));
        this.id = 0;
    }

    public void start(){
        Person bestPeople;
        for (Person next : playersList){
            marryArithmetic(next);
        }
    }

    /**
     * 把一个主角加入,让所有男生选出自己中意的女生
     * @param// person Person
     * @throws Exception Exception
     */
    private void marryArithmetic(Person person) {

        Person smartBoy;
        Person bastGirl;
        Person p;
        Person p_;
        HashMap> girls = new HashMap<>();

        int k = person.getId();

        if ( k ==0 ){           //主角加入
            person.setId(-1);
            this.mon.add(person);
        }else {
            person.setId(-1);
            this.man.add(person);
        }

        this.maleList =(ArrayList) man.clone();
        this.femaleList =(ArrayList) mon.clone();
        int size = this.man.size()>this.mon.size()? this.mon.size() : this.man.size();

        for (int i = 0; i < size; i++) {

            girls = chooseGirl(girls);        //选出女生列表

            bastGirl= getBastGirl(girls);      //选出最受欢迎的女生

            smartBoy = girlsChoose(bastGirl, girls.get(bastGirl));         //让女生选出中意的男生

            if (k==1){
                 p  = smartBoy;
                 p_ = bastGirl;
            }else {
                p  = bastGirl;
                p_ = smartBoy;
            }
            if ( p ==person ) {
                id++;
                if (k == 0){
                    mon.remove(p);
                    System.out.println("第"+id+"组player加入:"+p_.getId()+" | "+" -1 ");
                }else {
                    man.remove(p);
                    System.out.println("第"+id+"组player加入:"+"-1 "+" | "+p_.getId());
                }
                return ;
            } else {
                maleList.remove(smartBoy);
                femaleList.remove(bastGirl);
            }
            girls.clear();
        }
        id++;
        System.out.println("第"+id+"组player加入:"+"     ");
    }

    /**
     * 女生在男生中选择一位男生
     * @param person person --获得男生选择最多的女生
     * @param arrayList ArrayList --男生列表
     * @return Person smartBoy --中意男生
     */
    private Person girlsChoose(Person person,ArrayList arrayList){

        Person smartBoy = null;
        int scout = 0;
        int maxScore = 0;

        for (Person next : arrayList){
            int score = next.getAppearance()+next.getCharacter()+next.getTreasure();
            if (scout<=countScore(person,next)){
                if (scout==countScore(person,next)){
                    if (scoresmartBoy.getId()){
                            continue;
                        }
                    }
                }
                smartBoy = next;
                maxScore = score;
                scout = countScore(person,next);
            }
        }
        return smartBoy;
    }

    /**
     * 选出最受欢迎的女生
     * @param girls HashMap
     * @return Person
     */
    private Person getBastGirl(HashMap girls){

        int max = 0;                  //男生们的人数
        Person bastGirl = null;       //最受欢迎的女生
        int maxScore = 0;

        Iterator>> iterator1 = girls.entrySet().iterator();
        Map.Entry> next;

        while (iterator1.hasNext()) {

            next = iterator1.next();
            int score = next.getKey().getAppearance()+next.getKey().getTreasure()+next.getKey().getCharacter();
            ArrayList arrayList = next.getValue();
            if (max <=arrayList.size()) {
                if (max == arrayList.size()){
                    if (scorebastGirl.getId()){
                            continue;
                        }
                    }
                }
                maxScore = score;
                bastGirl = next.getKey();
                max = arrayList.size();
            }
        }
        return bastGirl;
    }

    /**
     * 选出选择女生的列表
     * @param girls HashMap>   女生列表
     * @return HashMap >   女生列表
     */
    private HashMap> chooseGirl(HashMap> girls){

        ArrayList list;
        Person likePerson;

        for (Person next :  this.maleList){              //遍历男生列表 让男生选出中意女生
            likePerson =  mateSort(next);         //让男生选出中意女子
            if (girls.containsKey(likePerson)) {
                list = girls.get(likePerson);
                list.add(next);
            } else {
                list = new ArrayList<>();
                list.add(next);
            }
            girls.put(likePerson, list);
        }
        return girls;
    }


    /**
     * 让指定男生在女生里面选一个中意女生
     * @param person Person 给定男生
     * @return Person 中意女生
     */
    private Person mateSort(Person person){
        int max = 0;                                   //最高得分
        Person likePerson = null;             //中意之人
        int maxScore = 0;                        //得分最高的人的前三项品质得分之和
        int score=0;                                 //当前的人的前三项品质得分之和

        for (Person next : femaleList){
            score = next.getAppearance()+next.getTreasure()+next.getCharacter();
            if (max<=countScore(person,next)){                           
                if ((max==(countScore(person,next)))){
                    if (score 已存储的数据
     * @throws Exception FileNotFoundException-->IOException
     */
    private ArrayList saveCount(String path) throws IOException {
    
        ArrayList hashmap = new ArrayList();
        BufferedReader bf = new BufferedReader(new FileReader(new File(path)));
        String line;
        
        while ((line= bf.readLine() )!= null) {
            hashmap.add(new Person (getNumber(line)[0],
                    getNumber(line)[1], getNumber(line)[2], getNumber(line)[3],
                    getNumber(line)[4], getNumber(line)[5], getNumber(line)[6]));
        }
        return hashmap;
    }

    /**
     * count score 
* count person to next * @param person Person ---- Person 's Look * @param next Person -----need itselves count * @return int --- next 's score */ private int countScore(Person person,Person next){ return person.getTreasureLook()*next.getTreasure()+ person.getCharacterLook()*next.getCharacter()+ person.getAppearanceLook()*next.getAppearance(); } }
main方法:
package com.tulun;

import com.tulun.main.Run;

public class App {
    
    public static void main(String[] args) throws Exception{

        String path1 = "/Users/liguozheng/Documents/FlayBird-1/marriage_mate/src/male.txt";
        String path2 = "/Users/liguozheng/Documents/FlayBird-1/marriage_mate/src/female.txt";
        String path3 = "/Users/liguozheng/Documents/FlayBird-1/marriage_mate/src/players.txt";

        Run a = new Run(path1,path2,path3);
        long start = System.currentTimeMillis();
        a.start();
        long end = System.currentTimeMillis();
        System.out.println(end-start+" ms");

    }
}
结果:
![结果](https://img-blog.csdnimg.cn/20181111181133111.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzU4ODA2Nw==,size_16,color_FFFFFF,t_70) ![结果](https://img-blog.csdnimg.cn/20181111181104895.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzU4ODA2Nw==,size_16,color_FFFFFF,t_70)
另外实测1000组数据,耗时8分钟左右。

你可能感兴趣的:(集合)