Map和Set—数据结构

news2024/11/24 13:32:56

文章目录

  • 1.搜索
    • 1.1常见搜索方式
    • 1.2模型
  • 2.map
    • 2.1介绍
    • 2.2 Map.Entry<K, V>
    • 2.3map的使用
    • 2.4遍历map
    • 2.5TreeMap和HashMap的区别
  • 3.set
    • 3.1介绍
    • 3.2set的使用
    • 3.3遍历set
    • 3.4 TreeSet和HashSet的不同
  • 4.搜索树
    • 4.1概念
    • 4.2实现
    • 4.3性能分析
  • 5.哈希表
    • 5.1查找数据
    • 5.2冲突的概念
    • 5.3冲突的避免方法
    • 5.4冲突的解决方法
    • 5.5实现(简单类型)
    • 5.6实现(泛型)

1.搜索

1.1常见搜索方式

(1)直接遍历:时间复杂度会达到O(N)
(2)二分查找:时间复杂度O(logN)
(3)Map和set:一种专门用来进行搜索的容器或者数据结构,其搜索的效率与其具体的实例化子类有关

1.2模型

(1)k-v模型:map(key-value)
(2)k模型:set(key)

2.map

Map是一个接口类,该类没有继承自Collection,该类中存储的是<K,V>结构的键值对,并且K一定是唯一的,不能重复

2.1介绍

  1. Map是一个接口,不能直接实例化对象,如果要实例化对象只能实例化其实现类TreeMap或者HashMap
  2. Map中Key是唯一的,如果相同会被替代成最新的value,value是可以重复的
  3. 在Map中插入时,key不能为空,但是value可以为空
  4. Map中的Key可以全部分离出来,存储到Set中来进行访问(因为Key不能重复)
  5. Map中的value可以全部分离出来,存储在Collection的任何一个子集合中(value可能有重复)
  6. Map中键值对的Key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行重新插入

2.2 Map.Entry<K, V>

Map.Entry<K, V> 是Map内部实现的用来存放<key, value>键值对映射关系的内部类

public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("hello",2);
        map.put("world",4);
        map.put("school",6);
        System.out.println(map);//{world=4, school=6, hello=2}
        //通过map.entrySet遍历key和value
        Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
        for (Map.Entry<String,Integer> entry:entrySet){
            //key:world  val:4 key:school  val:6 key:hello  val:2
            System.out.print("key:"+entry.getKey()+"  val:"+entry.getValue()+" ");
        }
        System.out.println();
        //将键值对中的value替换为指定value
        for (Map.Entry<String,Integer> entry:entrySet){
            //4 6 2
            System.out.print(entry.setValue(entry.getValue())+" ");
        }
    }

2.3map的使用

public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("hello",2);
        map.put("world",4);
        map.put("school",6);//设置 key 对应的 value
        System.out.println(map);//{world=4, school=6, hello=2}
        //存储顺序和打印的顺序不同是由于他的底层是通过哈希函数计算的
        System.out.println(map.get("hello"));//2 返回 key 对应的 value
        System.out.println(map.getOrDefault("hello", 4));//2 返回 key 对应的 value,key 不存在,返回默认值
        System.out.println(map.remove("world"));//4 删除 key 对应的映射关系
        System.out.println(map.keySet());//[school, hello] 返回所有 key 的不重复集合
        System.out.println(map.values());//[6, 2] 返回所有 value 的可重复集合
        System.out.println(map.entrySet());//[school=6, hello=2] 返回所有的 key-value 映射关系
        System.out.println(map.containsKey("world"));//false 判断是否包含 key
        System.out.println(map.containsValue(2));//true 判断是否包含 value
    }

2.4遍历map

public static void main(String[] args){
        Map<String,Integer> map = new HashMap<>();
        map.put("hello",2);
        map.put("world",4);
        map.put("school",6);
        System.out.println(map);//{world=4, school=6, hello=2}
        //通过map.keySet遍历key和value
        for (String key:map.keySet()){
            //key:world value:4 key:school value:6 key:hello value:2
            System.out.print("key:"+key+" value:"+map.get(key)+" ");
        }
        System.out.println();
        //通过map.values遍历value
        for (Integer value:map.values()){
            //4 6 2
            System.out.print(value+" ");
        }
        System.out.println();
        //集合方式遍历key
        Set<String> set = map.keySet();
        System.out.println(set);//[world, school, hello]
        //集合方式遍历value
        Collection<Integer> collection = map.values();
        System.out.println(collection);//[4, 6, 2]
        //通过map.entrySet遍历key和value
        Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
        for (Map.Entry<String,Integer> entry:entrySet){
            //key:world  val:4 key:school  val:6 key:hello  val:2
            System.out.print("key:"+entry.getKey()+"  val:"+entry.getValue()+" ");
        }
        System.out.println();
        //Map.Entry<>迭代器
        Set<Map.Entry<String,Integer>> entrySet1 = map.entrySet();
        Iterator<Map.Entry<String,Integer>> iterator = entrySet1.iterator();
        while (iterator.hasNext()){
            Map.Entry<String,Integer> entry = iterator.next();
            //key:world  val:4 key:school  val:6 key:hello  val:2
            System.out.print("key:"+entry.getKey()+"  val:"+entry.getValue()+" ");
        }
        System.out.println();
        //java8特有的遍历方法
        map.forEach((key,value)->{
            //key:world value:4 key:school value:6 key:hello value:2
            System.out.print("key:"+key+" value:"+value+" ");
        });
    }

2.5TreeMap和HashMap的区别

在这里插入图片描述

3.set

3.1介绍

  1. Set是继承自Collection的接口类,Set中只存储了Key,并且要求key唯一
  2. Set的底层是使用Map来实现的,其使用key与Object的一个默认对象作为键值对插入到Map中的
  3. Set最大的功能就是对集合中的元素进行去重
  4. 实现Set接口的常用类有TreeSet和HashSet
  5. Set中的Key不能修改,如果要修改,先将原来的删除掉,然后再重新插入
  6. Set中不能插入null的key

3.2set的使用

public static void main(String[] args) {
        //set不能添加重复元素
        Set<String> set = new HashSet<>();
        set.add("hello");
        set.add("world");
        set.add("world");
        set.add("school");//添加元素
        System.out.println(set);//[world, school, hello]
        System.out.println(set.contains("hello"));//true
        System.out.println(set.contains("d"));//false 是否包含某个元素
        System.out.println(set.remove("hello"));//true;
        System.out.println(set.remove("d"));//false 删除某个元素
        System.out.println(set.size());//2 返回set中元素的个数
        System.out.println(set.isEmpty());//false 检测set是否为空
        List<String> list = new ArrayList<>();
        list.add("abc");
        list.add("def");
        list.add("fag");
        set.addAll(list);//将集合c中的元素添加到set中
        System.out.println(set);//[world, abc, def, school, fag]
        set.clear();//清空set
}

3.3遍历set

public static void main(String[] args) {
        //set不能添加重复元素
        Set<String> set = new HashSet<>();
        set.add("hello");
        set.add("world");
        set.add("school");//添加元素
        System.out.println(set);//[world, school, hello]
        //使用toArray(),将set中的元素转换为数组返回,对数组进行遍历
        Object[] array = set.toArray();
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+" ");//world school hello
        }
        System.out.println();
        //使用toArray(T[] a),传递一个数组,把集合中的元素存储到数组中
        String[] array1 = new String[set.size()];
        String[] strings = set.toArray(array1);
        for (int i = 0; i < strings.length; i++) {
            System.out.print(strings[i]+" ");//world school hello
        }
        System.out.println();
        //使用迭代器遍历
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.print(iterator.next()+" ");//world school hello
        }
    }

3.4 TreeSet和HashSet的不同

在这里插入图片描述

4.搜索树

4.1概念

二叉搜索树(二叉排序树):每一棵树的左子树小于根结点,右子树大于根结点,也可以是一棵空树
在这里插入图片描述

4.2实现

public class BinaryTree {
    static class TreeNode{
        public int val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode(int val){
            this.val = val;
        }
    }
    public static TreeNode root;
    //查找二叉搜索树中是否包含某个元素
    public static boolean search(int val){
        if (root == null){
            return false;
        }
        TreeNode cur = root;
        while (cur!=null){
            //找到val
            if(cur.val==val){
                return true;
            }else if (cur.val>val){
                //大于val,在左子树找
                cur = cur.left;
            }else {
                //小于val,在左子树找
                cur = cur.right;
            }
        }
        return false;
    }
    //添加一个元素到二叉搜索树中
    public static boolean insert(int val) {
    //空树,直接插入到根结点
        if (root == null){
            root = new TreeNode(val);
        }
        TreeNode cur = root;
        TreeNode tmp = null;
        //找到插入位置的父亲结点
        while (cur!=null){
            if (cur.val > val){
                tmp = cur;
                cur = cur.left;
            }else if (cur.val < val){
                tmp = cur;
                cur = cur.right;
            }else {
                return false;
            }
        }
        if (tmp.val < val){
            tmp.right = new TreeNode(val);
        }else {
            tmp.left = new TreeNode(val);
        }
        return true;
    }

    //中序遍历二叉树
    public static void inorder(TreeNode root) {
        if (root == null){
            return;
        }
        inorder(root.left);
        System.out.print(root.val+" ");
        inorder(root.right);
    }
    //删除元素
    public static boolean remove(int key){
        if (root == null){
            return false;
        }
        TreeNode cur = root;
        TreeNode parent = null;
        //找到删除结点和要删除的结点的父节点
        while (cur != null){
            if (cur.val > key){
                parent = cur;
                cur = cur.left;
            }else if(cur.val < key){
                parent = cur;
                cur = cur.right;
            }else {
                removeNode(cur,parent);
                return true;
            }
        }
        return false;
    }
    public static void removeNode(TreeNode cur,TreeNode parent){
        if (cur.left == null){
            if (cur == root){
                root = root.right;
            }else if (parent.right == cur){
                parent.right = cur.right;
            }else {
            //parent.left == cur
                parent.left = cur.right;
            }
        }else if (cur.right == null){
            if (cur == root){
                root = root.left;
            }else if (parent.right == cur){
                parent.right = cur.left;
            }else {
            //parent.left == cur
                parent.left = cur.left;
            }
        }else {
        //cur.left!=null&&cur.right!=null
        //使用替代法删除,此处在右树找最小值
            TreeNode target = cur.right;
            TreeNode targetParent = cur;
            while (target.left != null){
                targetParent = target;
                target = target.left;
            }
            cur.val = target.val;
            if (target == targetParent.left){
                targetParent.left = target.right;
            }else {
                targetParent.right = target.right;
            }
        }
    }
}

4.3性能分析

(1)单分支的树:时间复杂度为N
(2)改进:AVL树(高度平衡的二叉树)、红黑树(RBTree)

5.哈希表

存储和取数据的时候都会遵守某种规则,称作哈希函数,哈希函数是可以自己设定的,构造出来的结构称哈希表(散列表),用该方法进行搜索不需要进行多次关键码的比较,因此搜索的效率比较高

5.1查找数据

(1)顺序查找:时间复杂度O(N)
(2)二分查找:时间复杂度O(logN)
(3)哈希表:增删查改的时间复杂度都可以达到O(1)

5.2冲突的概念

不同关键字通过相同哈希哈数计算出相同的哈希地址,该种现象称为哈希冲突或哈希碰撞

5.3冲突的避免方法

冲突的发生是必然的,我们只能尽量降低冲突的发生频率
(1)设计合理的哈希函数
设计原则:哈希函数定义域必须包括需要存储的全部关键码;哈希函数计算出来的地址能均匀分布在整个空间中;哈希函数应该比较简单
(2)调节负载因子
a,散列表的负载因子=填入表中的元素的个数/散列表的长度
b,负载因子和冲突率的关系
在这里插入图片描述
c,超过负载因子就需要扩容
d,想要降低冲突率就只能减少负载因子,想要减少负载因子就只能增加散列表的长度

5.4冲突的解决方法

(1)闭散列(开放定址法):空间利用率低
a,线性探测:放到冲突位置的下一个空的地方(不好删除;会把冲突元素放到一起)
b,二次探测:使用Hi = (H0+i^2)%m放到下一个空的地方(i是冲突的次数,H0是冲突的位置,m是散列表的长度)
(2)开散列(哈希桶/链地址法/开链法):把所有的元素挂到链表上,JDK1.8使用的是尾插法
a,解决:数组+链表+红黑树(树化是有条件的)
b,树化的条件:链表的长度超过8;数组的长度超过64
c,把红黑树变为链表的条件:树的结点为6
在这里插入图片描述
d,哈希表的扩容要注意:重新哈希

5.5实现(简单类型)

public class HashBuck {
    static class Node{
        public int key;
        public int val;
        public Node next;
        public Node(int key,int val){
            this.key = key;
            this.val = val;
        }
    }
    public int usedSize;//存放数据个数
    public static final double FACTOR = 0.75;//负载因子
    public Node[] array;
    public HashBuck(){
        this.array = new Node[8];
    }
    //插入元素
    public boolean put(int key,int val){
        Node node = new Node(key,val);
        //1、找到要插入下标的位置
        int index = key % array.length;
        //2、遍历这个下标的链表,看看有没有一样的值
        Node cur = array[index];
        while (cur!=null){
            if (cur.key == key){
                cur.val = val;//更新val的值
                return false;
            }
            cur = cur.next;
        }
        //3、遍历完成当前链表的值,若没有相同的就开始插入
        cur = array[index];
        node.next = cur;
        array[index] = node;
        this.usedSize++;
        //4、存放元素之后,判断当前哈希桶中的负载因子是否超过默认的负载因子
        if (loadFactor() >= FACTOR){
            //5、扩容
            resize();
        }
        return true;
    }
    //扩容
    private void resize(){
        //1、更新数组长度,申请二倍数组长度
        Node[] tmp = new Node[this.array.length*2];
        //2、遍历原来的数组,将每个小标的节点的数据都进行重新哈希
        for (int i = 0; i < array.length; i++) {
            Node cur = array[i];
            while (cur!=null){
                Node curNext = cur.next;
                int newIndex = cur.key % tmp.length;//新的数组的下标
                cur.next = tmp[newIndex];
                tmp[newIndex] = cur;
                cur = curNext;
            }
        }
        array = tmp;
    }
    //得到负载因子的值
    private double loadFactor(){
        return this.usedSize*1.0/this.array.length;
    }
    //获取val的值
    public int get(int key){
        int index = key % array.length;
        Node cur = array[index];
        while (cur != null){
            if (cur.key == key){
                return cur.val;
            }
            cur = cur.next;
        }
        return -1;
    }
}
//测试
public static void main(String[] args) {
        HashBuck h = new HashBuck();
        h.put(1,1);
        h.put(2,2);
        h.put(3,3);
        h.put(6,4);
        h.put(14,14);
        h.put(17,17);
        h.put(24,24);
        System.out.println('a');//在此处打断点
    }

5.6实现(泛型)

HashMap:

class Person{
    public String id;
    public Person(String id) {
        this.id = id;
    }
    @Override
    public String toString() {
        return "person{" +
                "id='" + id + '\'' +
                '}';
    }
    //找到下标下和key一样的结点
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return Objects.equals(id, person.id);
    }
    //找到下标的节点
    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}
public static void main(String[] args) {
        HashMap<Person,String> hashMap = new HashMap<>();
        Person p1 = new Person("12345");
        Person p2 = new Person("12345");
        hashMap.put(p1,"xian");
        System.out.println(hashMap.get(p2));//xian
    }

注意:
(1)以后我们自己定义的类一定要重写equals和HashCode,要知道HashCode一样,equals不一定一样,equals一样,HashCode一定一样
(2)HashSet的底层是一个HashMap(原码中HashSet存的元素作为HashMap的key,不能重复)
(3)map第一次添加元素的时候,容量才会赋予16

public class HashBuck2<k,v> {
    static class Node<k,v>{
        public k key;
        public v val;
        public Node<k,v> next;
        public Node(k key,v val){
            this.key = key;
            this.val = val;
        }
    }
    public Node<k,v>[] array = (Node<k,v>[])new Node[8];
    public static final double FACTOR = 0.75;//负载因子
    public int usedSize;
    public void put(k key,v val){
        Node<k,v> node = new Node<>(key,val);
        //1、找到要插入的下标位置
        int hash = key.hashCode();//将key变成一个整数
        int index = hash % array.length;
        //2、遍历这个下标的链表,看看有没有一样的值
        Node<k,v> cur = array[index];
        while (cur!=null){
            if (cur.key.equals(key)){
                cur.val = val;//更新val的值
            }
            cur = cur.next;
        }
        //3、遍历完成当前链表的值,若没有相同的就开始插入
        cur = array[index];
        node.next = cur;
        array[index] = node;
        this.usedSize++;
        //4、存放元素之后,判断当前哈希桶中的负载因子是否超过默认的负载因子
        if (loadFactor() >= FACTOR){
            //5、扩容
            resize();
        }
    }
    //扩容
    private void resize(){
        //1、更新数组长度,申请二倍数组长度
        Node<k,v>[] tmp = new Node[this.array.length*2];
        //2、遍历原来的数组,将每个小标的节点的数据都进行重新哈希
        for (int i = 0; i < array.length; i++) {
            Node<k,v> cur = array[i];
            while (cur!=null){
                Node<k,v> curNext = cur.next;
                int hash = array[i].hashCode();//将key变成一个整数
                int newIndex = hash % array.length;//新的数组的下标
                cur.next = tmp[newIndex];
                tmp[newIndex] = cur;
                cur = curNext;
            }
        }
        array = tmp;
    }
    //得到负载因子的值
    private double loadFactor(){
        return this.usedSize*1.0/this.array.length;
    }
    //获取val的值
    public v get(k key){
        int hash = key.hashCode();
        int index = hash % array.length;
        Node<k,v> cur = array[index];
        while (cur != null){
            if (cur.key.equals(key)){
                return cur.val;
            }
            cur = cur.next;
        }
        return null;
    }
}
//测试
public static void main(String[] args) {
        HashBuck2<Person,String> hashBuck2 = new HashBuck2<>();
        Person p1 = new Person("12345");
        Person p2 = new Person("12345");
        hashBuck2.put(p1,"xian");
        System.out.println(hashBuck2.get(p2));//xian
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/922933.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一个新的品牌如何快速做好品牌宣传?媒介盒子有绝招

互联网快速发展的今天&#xff0c;大量信息进入人们的生活&#xff0c;只要有流量就将成为广告的渠道。今天这里提到的是新品牌&#xff0c;相比较而言又具有一定的特殊性。 新品牌可能是一个创业公司&#xff0c;刚刚研发出来的品牌&#xff0c;想要冲进这个信息化的市场&…

libjpeg实践1:源码编译和MJPG转BMP测试:

编译源码 下载源码 http://www.ijg.org/files/ wget http://www.ijg.org/files/jpegsrc.v9b.tar.gz解压&#xff1a; tar zxvf jpegsrc.v9b.tar.gz 开始配置和编译&#xff0c;因为是在ubuntu中测试。所以配置很简单 ./configure --prefix/home/lkmao/linux/3588-linux/…

SpringBoot 2.7 集成 Netty 4 解决粘包半包问题

文章目录 1 摘要2 核心代码2.1 Netty 服务端连接器2.2 Netty 客户端连接器2.3 Netty 服务端 Handler2.4 Netty 客户端 Handler 3 推荐参考资料4 Github 源码 1 摘要 Netty 的粘包和半包问题是由于 Netty 在接收消息时无法判断消息是否发送完毕&#xff0c;只能靠读取消息时是否…

每天一分享#读up有感#

不知道开头怎么写&#xff0c;想了一下&#xff0c;要不&#xff0c;就这样吧&#xff0c;开头也就写完 今日分享 分享一博主的分享——https://blog.csdn.net/zhangay1998/article/details/121736687 全程高能&#xff0c;大佬就diao&#xff0c;一鸣惊人、才能卓越、名扬四…

算法通关村十二关 | 字符串前缀问题

1. 最长公共前缀 题目&#xff1a;LeetCode14&#xff0c;14. 最长公共前缀 - 力扣&#xff08;LeetCode&#xff09; 思路一 我们先看公共前缀有什么特点。 第一种方式&#xff0c;竖着比较&#xff0c;如图左边所示&#xff0c;选取数组中第一个字符串的位置&#xff0c;每…

platform相关资料

Step 1: Hardware Settings for Vitis Platform — Vitis™ Tutorials 2021.2 documentationhttps://xilinx.github.io/Vitis-Tutorials/2021-2/build/html/docs/Vitis_Platform_Creation/Introduction/03_Edge_VCK190/step1.html https://www.cnblogs.com/VagueCheung/p/1313…

Tensoeboard的一些坑与技巧

安装 pip install tensorboard 安装过程中遇到tensoeboard.exe找不到&#xff0c;参考解决&#xff1a; https://blog.csdn.net/weixin_44532467/article/details/123525891 3.启动tensorboard 默认路径 &#xff08;&#xff09; tensorboard --logdir logstensorboard -…

淘宝API技术解析,实现获得淘宝APP商品详情原数据

淘宝API&#xff08;Application Programming Interface&#xff09;是为开发者提供的一组接口&#xff0c;用于与淘宝平台进行数据交互。通过使用淘宝API&#xff0c;开发者可以获得淘宝平台上商品、店铺、订单等各种数据&#xff0c;并进行相应的业务操作。 要实现获取淘宝A…

利用Kettle进行SQLServer与Oracle之间的数据迁移实践

待更新 https://it.cha138.com/tech/show-1275283.html

基于spring boot校园疫情信息管理系统/疫情管理系统

摘要 随着计算机技术&#xff0c;网络技术的迅猛发展&#xff0c;Internet 的不断普及&#xff0c;网络在各个领域里发挥了越来越重要的作用。特别是随着近年人民生活水平不断提高&#xff0c;校园疫情信息管理系统给学校带来了更大的帮助。 由于当前疫情防控形势复杂&#xff…

史上最全软件测试入门到精通【测试+测开】

测试学习大纲梳理 根据本人过往学习经验与理解&#xff0c;整理了一些关于测试学习内容与顺序&#xff0c;涵盖了基本软件测试工程师需要掌握的所有技能&#xff0c;希望可以给想了解的小伙伴们一些指引与帮助&#xff0c;有错误或需求的欢迎留言指出~ 一、web开发者模式 这…

[LeetCode周赛复盘] 第 359 场周赛20230820

[LeetCode周赛复盘] 第 359 场周赛20230820 一、本周周赛总结2828. 判别首字母缩略词1. 题目描述2. 思路分析3. 代码实现 2829. k-avoiding 数组的最小总和1. 题目描述2. 思路分析3. 代码实现 2830. 销售利润最大化1. 题目描述2. 思路分析3. 代码实现 2831. 找出最长等值子数组…

【智算中心】国产GPU横向对比

近日&#xff0c;沐曦发布了一篇名为《沐曦与智谱AI完成兼容性测试 共建软硬件一体化解决方案》的公众号&#xff0c;表示曦云C500千亿参数AI大模型训练及通用计算GPU与智谱AI开源的中英双语对话语言模型ChatGLM2-6B完成适配。测试结果显示&#xff0c;曦云C500在智谱AI的升级版…

V4L2+单色USB摄像头编程实践3:读取MJPG格式图像

查看摄像头支持的MJPG格式的分辨率和帧率&#xff1a; $ v4l2-ctl --list-formats-ext --device /dev/video0 ioctl: VIDIOC_ENUM_FMTType: Video Capture[0]: MJPG (Motion-JPEG, compressed)Size: Discrete 1280x720 Interval: Discrete 0.008s (120.000 fps)Interval:…

敏捷研发管理软件及敏捷管理流程

Scrum中非常强调公开、透明、直接有效的沟通&#xff0c;这也是“可视化的管理工具”在敏捷开发中如此重要的原因之一。通过“可视化的管理工具”让所有人直观的看到需求&#xff0c;故事&#xff0c;任务之间的流转状态&#xff0c;可以使团队成员更加快速适应敏捷开发流程。 …

Java cc链2 分析

环境 cc4 <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 --> <dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.0</version&…

损失函数介绍

用softmax&#xff0c;就可以将一个输出值转换到概率取值的一个范围。 交叉熵损失CrossEntropyLoss 第一个参数weight&#xff0c; 各类别的loss设置权值&#xff0c; 如果类别不均衡的时候这个参数很有必要了&#xff0c;加了之后损失函数变成这样&#xff1a; 第二个参数ign…

8年测试经验之谈 —— 什么是全链路压测?

随着互联网技术的发展和普及&#xff0c;越来越多的互联网公司开始重视性能压测&#xff0c;并将其纳入软件开发和测试的流程中。 阿里巴巴在2014 年双11 大促活动保障背景下提出了全链路压测技术&#xff0c;能更好的保障系统可用性和稳定性。 什么是全链路压测&#xff1f; …

湘潭大学 湘大 XTU 1251 Colombian Number 题解(非常详细)

参考文章 1.XTUOJ-1251-Colombian Number 链接 1251 题面 题目描述 对于正整数n,不存在整数k,使得n等于k加上k的数码累加和&#xff0c;我们称这样的数是哥伦比亚数或者自我数。 比如 11就不是一个哥伦比亚数&#xff0c;因为10加上10的数码累加和1等于11;而20则是一个哥伦…

uniapp 开发微信小程序使用echart的dataZoom属性缩放功能不生效!bug记录!

在本项目中使用的是这个echart库 在项目中添加了dataZoom配置项但是不生效&#xff0c;突然想到微信小程序代码大小的限制&#xff0c;之前的echarts.js是定制的&#xff0c;有可能没有加dataZoom组件。故重新定制echarts.js。之前用的echarts版本是5.0.0&#xff0c;这次也是…