概述
学习记录来自:能解决一切答案 bravo1988 - 知乎博主(可购买其小册)
这个算法能解决什么问题呢?它主要处理两个数据集合的匹配问题。
比如,现在有两个数据集合:
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;
}
要求对数据进行处理,最终输出:
梁山伯爱祝英台
牛郎爱织女
干将爱莫邪
工藤新一爱毛利兰
罗密欧爱朱丽叶
第一版算法
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);
}
}
第二版算法
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);
}
}
第三版算法
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);
}
}
第四版算法
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);
}
}
最后
以上就是快乐发夹为你收集整理的数据集匹配算法(Java)第一版算法第二版算法第三版算法第四版算法的全部内容,希望文章能够帮你解决数据集匹配算法(Java)第一版算法第二版算法第三版算法第四版算法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复