Algoritmo de coincidencia de conjuntos de datos (Java)

Registros de aprendizaje de: puede resolver todas las respuestas bravo1988 - conocer el blogger (puede comprar su folleto)

¿Qué problema puede resolver este algoritmo? Se ocupa principalmente del problema de coincidencia de dos conjuntos de datos .

Por ejemplo, ahora hay dos conjuntos de datos:

public class Demo {

    public static void main(String[] args) {

        // 老公组
        List<Couple> husbands = new ArrayList<>();
        husbands.add(new Couple(1, "梁山伯"));
        husbands.add(new Couple(2, "牛郎"));
        husbands.add(new Couple(3, "干将"));
        husbands.add(new Couple(4, "工藤新一"));
        husbands.add(new Couple(5, "罗密欧"));

        // 老婆组
        List<Couple> wives = new ArrayList<>();
        wives.add(new Couple(1, "祝英台"));
        wives.add(new Couple(2, "织女"));
        wives.add(new Couple(3, "莫邪"));
        wives.add(new Couple(4, "毛利兰"));
        wives.add(new Couple(5, "朱丽叶"));
    }
}

@Data
@AllArgsConstructor
class Couple{
    private Integer familyId;
    private String userName;
}

Los datos deben procesarse y el resultado final es:

Liang Shanbo ama a Zhu Yingtai

Tejedora de amor de pastor de vacas

chismes amor moxie

Kudo Shinichi Ai Maurilan

Romeo ama a Julieta

La primera versión del algoritmo.

package com.wei.demo.Controller;

import java.util.LinkedList;
import java.util.List;

public class NumberOne {
    public static void main(String[] args) {
        //循环次数
        int count = 0;
        //第一个集合数据
        List<Couple> husbands = new LinkedList<>();
        husbands.add(new Couple(1, "梁山伯"));
        husbands.add(new Couple(2, "牛郎"));
        husbands.add(new Couple(3, "干将"));
        husbands.add(new Couple(4, "工藤新一"));
        husbands.add(new Couple(5, "罗密欧"));
        //第二个集合数据
        List<Couple> wives = new LinkedList<>();
        wives.add(new Couple(1, "祝英台"));
        wives.add(new Couple(2, "织女"));
        wives.add(new Couple(3, "莫邪"));
        wives.add(new Couple(4, "毛利兰"));
        wives.add(new Couple(5, "朱丽叶"));

        //如何把两个数据集合进行有效的匹配呢?比如梁山伯 爱 祝英台 就是1对1 2对2 ,男嘉宾需要找到属于自己的号码牌的女嘉宾
       /**
         * 首先是常规的方法for循环,好的算法是不断进行迭代的,刚开始都是从完成需求进行开始
         */
        for (Couple husband :
                husbands) {
            for (Couple wife :
                    wives) {
                //记录循环的次数
                count++;
                if (husband.getId().equals(wife.getId())) {

                    System.out.println(husband.getName()+"爱"+wife.getName());
                }
            }
        }
        System.out.println("------循环结束------");
        System.out.println("循环次数为:"+count);
    }
    
}

Algoritmo de la segunda edición

package com.wei.demo.Controller;

import java.util.LinkedList;
import java.util.List;

public class NumberTwo {
    public static void main(String[] args) {
        //循环次数
        int count = 0;
        //第一个集合数据
        List<Couple> husbands = new LinkedList<>();
        husbands.add(new Couple(1, "梁山伯"));
        husbands.add(new Couple(2, "牛郎"));
        husbands.add(new Couple(3, "干将"));
        husbands.add(new Couple(4, "工藤新一"));
        husbands.add(new Couple(5, "罗密欧"));
        //第二个集合数据
        List<Couple> wives = new LinkedList<>();
        wives.add(new Couple(1, "祝英台"));
        wives.add(new Couple(2, "织女"));
        wives.add(new Couple(3, "莫邪"));
        wives.add(new Couple(4, "毛利兰"));
        wives.add(new Couple(5, "朱丽叶"));

        //如何把两个数据集合进行有效的匹配呢?比如梁山伯 爱 祝英台
         /**
         * 第一种方法循环次数是25次,速度慢,需要进一步的改进
         * 在内层循环时,当匹配到后,我们可以加一个break,不需要再次无用的循环了
         * 循环次数是15次
         */
        for (Couple husband :
                husbands) {
            for (Couple wife :
                    wives) {
                //记录循环的次数
                count++;
                if (husband.getId().equals(wife.getId())) {

                    System.out.println(husband.getName()+"爱"+wife.getName());
                    break;
                }
            }
        }
        System.out.println("------循环结束------");
        System.out.println("循环次数为:"+count);
    }
    
}

Algoritmo de la tercera edición

package com.wei.demo.Controller;

import java.util.LinkedList;
import java.util.List;

public class NumberThree {
    public static void main(String[] args) {
        //循环次数
        int count = 0;
        //第一个集合数据
        List<Couple> husbands = new LinkedList<>();
        husbands.add(new Couple(1, "梁山伯"));
        husbands.add(new Couple(2, "牛郎"));
        husbands.add(new Couple(3, "干将"));
        husbands.add(new Couple(4, "工藤新一"));
        husbands.add(new Couple(5, "罗密欧"));
        //第二个集合数据
        List<Couple> wives = new LinkedList<>();
        wives.add(new Couple(1, "祝英台"));
        wives.add(new Couple(2, "织女"));
        wives.add(new Couple(3, "莫邪"));
        wives.add(new Couple(4, "毛利兰"));
        wives.add(new Couple(5, "朱丽叶"));

        //如何把两个数据集合进行有效的匹配呢?比如梁山伯 爱 祝英台
         /**
         * 第二种方法,我们可以看到已经从25次缩减到15次,有了一定的进步
         * 但是,我们想,如果前面两个人已经匹配成功后,那这个妻子就不能再匹配了,相当于要删除了,不然后面还要进行不断地重复循环。
         * 所以我们可以加remove方法
         */
        for (Couple husband :
                husbands) {
            for (Couple wife :
                    wives) {
                //记录循环的次数
                count++;
                if (husband.getId().equals(wife.getId())) {

                    System.out.println(husband.getName()+"爱"+wife.getName());
                    wives.remove(wife);
                    break;
                }
            }
        }
        System.out.println("------循环结束------");
        System.out.println("循环次数为:"+count);
    }
    
}

Algoritmo de la Cuarta Edición

package com.wei.demo.Controller;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class NumberFour {
    public static void main(String[] args) {
        //循环次数
        int count = 0;
        //第一个集合数据
        List<Couple> husbands = new LinkedList<>();
        husbands.add(new Couple(1, "梁山伯"));
        husbands.add(new Couple(2, "牛郎"));
        husbands.add(new Couple(3, "干将"));
        husbands.add(new Couple(4, "工藤新一"));
        husbands.add(new Couple(5, "罗密欧"));
        //第二个集合数据
        List<Couple> wives = new LinkedList<>();
        wives.add(new Couple(1, "祝英台"));
        wives.add(new Couple(2, "织女"));
        wives.add(new Couple(3, "莫邪"));
        wives.add(new Couple(4, "毛利兰"));
        wives.add(new Couple(5, "朱丽叶"));

        //如何把两个数据集合进行有效的匹配呢?比如梁山伯 爱 祝英台
        /**
         * 第三种的算法已经把次数减到5次了,已经是比较大改善,比第一个算法次数少了5倍
         * 但是如果把第三种算法的次数颠倒过来,比如把男嘉宾的12345次序改为54321,你可以观察一下效果,次数又变成15次,这说明这个算法的平均性能不高
         * 但是我们想一下,如果把list转map进行直接的定位匹配,而不需要直接进行遍历,那是不是更快吗?
         * 绝大多数情况下,for循环意味着抽取共同特性,忽略个体差异。好处是代码通用,坏处是无法发挥个体优势,最终影响效率
         * 如果我们给场上的女嘉宾每人发一个牌子,让他们在上面写上自己喜欢的男嘉宾号码,那么男嘉宾上场后就不用挨个问了,直接找到写有自己号码的女嘉宾即可牵手成功。
         * 这个算法的思想其实就是让数据产生差异化,外部通过差异快速定位目标数据
         * 这个算法无论次数怎么颠倒依然是10次,所以综合性能更好,它的精髓就是利用HashMap给其中一列数据加了“索引”,每个数据的“索引”(Map的key)是不同的,让数据差异化。
         */
        //给女嘉宾发牌子,然后男嘉宾直接看牌子直接进行匹配
        Map<Integer, Couple> wivesMap = new HashMap<>();
        for (Couple wife :
                wives) {
            //女嘉宾现在不在LIst集合中了,而是map中,在前面放了一块令牌,男嘉宾根据牌子直接定位进行匹配
            wivesMap.put(wife.getId(), wife);
            count++;
        }

        //然后男嘉宾进行匹配
        for (Couple husband :
                husbands) {
            //根据令牌号码直接定位到自己的女嘉宾,因为要号码牌一致啊1对1
            Couple wife = wivesMap.get(husband.getId());
             System.out.println(husband.getName()+"爱"+wife.getName());
            count++;
        }
        System.out.println("------循环结束-----");
        System.out.println("循环次数:"+count);
    }
    
}

Supongo que te gusta

Origin blog.csdn.net/qq_35207086/article/details/123233002
Recomendado
Clasificación