【红包 源码】【电脑抽奖源码】【搬家交易源码】集合 size源码_集合源码解析

2024-12-26 04:18:31 来源:青岛视觉设计源码 分类:综合

1.[stl 源码分析] std::list::size 时间复杂度
2.写出下面题目的集合集合解析程序代码(C++) 并且输入输出都截个图 谢谢~
3.ArrayList详解及扩容源码分析
4.HashSet 源码分析及线程安全问题

集合 size源码_集合源码解析

[stl 源码分析] std::list::size 时间复杂度

       在对Linux上C++项目进行性能压测时,一个意外的源码源码发现是std::list::size方法的时间复杂度并非预期的高效。原来,集合集合解析这个接口在较低版本的源码源码g++(如4.8.2)中是通过循环遍历整个列表来计算大小的,这导致了明显的集合集合解析性能瓶颈。@NagiS的源码源码红包 源码提示揭示了这个问题可能与g++版本有关。

       在功能测试阶段,集合集合解析CPU负载始终居高不下,源码源码通过火焰图分析,集合集合解析std::list::size的源码源码调用占据了大部分执行时间。火焰图的集合集合解析使用帮助我们深入了解了这一问题。

       查阅相关测试源码(源自cplusplus.com),源码源码在较低版本的集合集合解析g++中,std::list通过逐个节点遍历来获取列表长度,源码源码电脑抽奖源码这种操作无疑增加了时间复杂度。集合集合解析然而,对于更新的g++版本(如9),如_glibcxx_USE_CXX_ABI宏启用后,list的实现进行了优化。它不再依赖遍历,而是利用成员变量_M_size直接存储列表大小,从而将获取大小的时间复杂度提升到了[公式],显著提高了性能。具体实现细节可在github上找到,如在/usr/include/c++/9/bits/目录下的代码。

写出下面题目的程序代码(C++) 并且输入输出都截个图 谢谢~

       //记的以前学校时写过,好像是搬家交易源码POJ的题目。源代码还在电脑上留着,仅供参考

       #include <iostream>

       #include <cmath>

       using namespace std;

       const int MAXN = ;

       const int MAXM = ;

       const int MAXP = ;

       const int MAXT = 6;

       struct Tpoint {

        int x, y;

       };

       Tpoint u[MAXN],v[MAXN],w[MAXN],p[MAXN];

       int step[4][2] = { { 0,1}, { 0,-1}, { 1,0}, { -1,0}};

       int mark[MAXM][MAXM], map[MAXP][MAXP], board[MAXT][MAXT];

       int num, cnt, ver, size;

       bool cover[MAXM][MAXM];

       char line[MAXM][MAXM];

       //判断B集合中的连通性

       inline int connect(int x, int y)

       {

        int front = 0, rear = 1;

        w[rear].x = x; w[rear].y = y; board[x][y] = 0;

        while(front < rear) {

        front ++;

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

        int tx = w[front].x + step[i][0];

        int ty = w[front].y + step[i][1];

        if(tx >= 0 && tx < size && ty >= 0 && ty < size && board[tx][ty]) {

        board[tx][ty] = 0;

        rear++;

        w[rear].x = tx;

        w[rear].y = ty;

        }

        }

        }

        return rear;

       }

       //通过平移判断两个集合是否刚好构成N*N的图形

       inline bool match(int minx2, int miny2, int maxx2, int maxy2, int maxx1, int maxy1)

       {

        for(int i = maxx2 - size + 1; i < minx2 + size - maxx1; i ++) {

        for(int j = maxy2 - size + 1; j < miny2 + size - maxy1; j ++) {

        bool flag = true;

        for(int k = 0; k < num; k ++) {

        if(map[v[k].x+i][v[k].y+j]) {

        flag = false;

        break;

        }

        }

        if(flag) return true; //集合A和集合B刚好能组成size*size的正方形,返回true;

        }

        }

        return false;

       }

       inline bool ok(int minx2, int miny2, int maxx2, int maxy2) //参数传递集合A的边界

       {

        int i, j, minx1, miny1, maxx1, maxy1;

        minx1 = miny1 = ; maxx1 = maxy1 = 0;

        for(i = 0; i < ver; i ++) {

        if(! cover[p[i].x][p[i].y]) { //标记集合B的边界

        if(minx1 > p[i].x) minx1 = p[i].x;

        if(miny1 > p[i].y) miny1 = p[i].y;

        if(maxx1 < p[i].x) maxx1 = p[i].x;

        if(maxy1 < p[i].y) maxy1 = p[i].y;

        }

        }

        num = 0;

        memset(map, 0, sizeof(map));

        for(i = 0; i < ver; i ++) {

        if(! cover[p[i].x][p[i].y]) {

        if((p[i].x - minx1 >= size) || (p[i].y - miny1 >= size))

        return false;

        //集合B的边界超过size*size,返回false

        v[num].x = p[i].x - minx1; //将集合B往左上角移

        v[num].y = p[i].y - miny1;

        num ++;

        }else {

        map[p[i].x - minx2 + 5][p[i].y - miny2 + 5]=1; //将集合A往右下角移

        }

        }

        memset(board, 0, sizeof(board));

        for(i = 0; i < num; i ++)

        board[v[i].x][v[i].y] = 1;

        if(connect(v[0].x,v[0].y)<num) return false; //集合B不连通返回false

        maxx2 = maxx2 - minx2 + 5; maxy2 = maxy2 - miny2 + 5;

        minx2 = miny2 = 5;

        maxx1 = maxx1 - minx1; maxy1 = maxy1 - miny1;

        minx1 = miny1 = 0;

        for(i = 0; i < 4; i ++) { //4次旋转

        if(match(minx2, miny2, maxx2, maxy2, maxx1, maxy1))

        //集合A与B刚好能够组成size*size的正方形,返回true

        return true;

        minx1 = miny1 = INT_MAX; maxx1 = maxy1 = INT_MIN;

        for(j = 0; j < num; j ++) {

        int temp = v[j].y;

        v[j].y = size - v[j].x - 1;

        v[j].x = temp;

        if(minx1 > v[j].x) minx1 = v[j].x;

        if(miny1 > v[j].y) miny1 = v[j].y;

        if(maxx1 < v[j].x) maxx1 = v[j].x;

        if(maxy1 < v[j].y) maxy1 = v[j].y;

        }

        for(j = 0; j < num; j ++) {

        v[j].x -= minx1; v[j].y -= miny1; //将集合B往左上角移

        }

        maxx1 -= minx1;maxy1 -= miny1;

        }

        return false;

       }

       inline bool dfs(int minx, int miny, int maxx, int maxy, int m, int k)

       {

        if(k > m) return false;

        if(dfs(minx, miny, maxx, maxy, m, k + 1)) return true; //k点不属于集合A

        if(abs(u[k].x - minx) >= size || abs(u[k].y - miny) >= size ||

        abs(u[k].x - maxx) >= size || abs(u[k].y - maxy) >= size)

        //若集合A超过边界size,则返回false

        return false;

        int i, tx, ty;

        for(i = 0; i < 4; i ++) {

        tx = u[k].x + step[i][0];

        ty = u[k].y + step[i][1];

        if(line[tx][ty] == '*' && ! mark[tx][ty]) { //可扩展点进行标记

        m ++;

        u[m].x = tx;

        u[m].y = ty;

        mark[tx][ty] = k;

        }

        }

        cover[u[k].x][u[k].y] = true;

        if(ok(__min(minx, u[k].x), __min(miny, u[k].y), __max(maxx, u[k].x), __max(maxy, u[k].y)))

        //若刚好能组成size*size的正方形,则返回true

        return true;

        if(dfs(__min(minx, u[k].x), __min(miny, u[k].y), __max(maxx, u[k].x), __max(maxy,u[k].y), m, k + 1))//继续搜索集合A,若成功返回true

        return true;

        cover[u[k].x][u[k].y] = false;

        for(i = 0; i < 4; i ++) {

        tx = u[k].x + step[i][0];

        ty = u[k].y + step[i][1];

        if(mark[tx][ty] == k) mark[tx][ty] = 0; //消除标记

        }

        return false;

       }

       int main()

       {

        cnt = 0;

        while(gets(line[cnt++])); //读入数据

        ver = 0;

        for(int i = 0; i < cnt; i ++)

        for(int j = 0; line[i][j]; j ++)

        if(line[i][j] == '*') {

        p[ver].x = i; p[ver].y = j; ver ++;

        }

        size = (int)sqrt((double)ver); //正方形的边长为size

        memset(cover, false, sizeof(cover));

        memset(mark, 0, sizeof(mark));

        u[1].x = p[0].x; u[1].y = p[0].y;

        mark[u[1].x][u[1].y] = -1;

        dfs(u[1].x, u[1].y, u[1].x, u[1].y, 1, 1); //搜索集合A的可能情况

        for(i = 0; i < cnt; i ++) {

        for(int j = 0; line[i][j]; j ++) {

        if(line[i][j]=='*') {

        if(cover[i][j]) printf("A");

        else printf("B");

        }else printf(".");

        }

        printf("\n");

        }

        return(0);

       }

ArrayList详解及扩容源码分析

       在集合框架中,ArrayList作为普通类实现List接口,如下图所示。

       它实现了RandomAccess接口,表明支持随机访问;Cloneable接口,表明可以实现克隆;Serializable接口,明星九七源码表明支持序列化。

       与其他类不同,如Vector,ArrayList在单线程环境下的线程安全性较差,但适用于多线程环境下的Vector或CopyOnWriteArrayList。

       ArrayList底层基于连续的空间实现,为动态可扩展的顺序表。

       一、构造方法解析

       使用ArrayList(Collection c)构造方法时,传入类型必须为E或其子类。

       二、扩容分析

       不带参数的构造方法初始容量为,此时底层数组为空,kakadu源码优化即`DEFAULT_CAPACITY_EMPTY_ELEMENTDATA`长度为0。

       元素添加时,默认插入数组末尾,调用`ensureCapacityInternal(size + 1)`增加容量。

       若当前容量无法满足增加需求,计算新的容量以达到所需规模,确保添加元素成功并避免频繁扩容。

       三、常用方法

       通过List.subList(int fromIndex, int toIndex)方法获取子列表,修改原列表元素亦会改变此子列表。

       四、遍历方式

       ArrayList提供for循环、foreach循环、迭代器三种遍历方法。

       五、缺陷与替代方案

       ArrayList基于数组实现,插入或删除元素导致频繁元素移动,时间复杂度高。在需要任意位置频繁操作的场景下,性能不佳。

       因此,在Java集合中引入了更适合频繁插入和删除操作的LinkedList类。

       版权声明:本文内容基于阿里云实名注册用户的贡献,遵循相关协议规定,包括用户服务协议和知识产权保护指引。发现抄袭内容,可通过侵权投诉表单举报,确保社区内容健康、合规。

HashSet 源码分析及线程安全问题

       HashSet,作为集合框架中的重要成员,其底层采用 HashMap 进行数据存储,简化了集合操作的复杂性。深入理解 HashMap,将有助于我们洞察 HashSet 的源码精髓。

       一、HashSet 定义详解

       1.1 构造函数

       HashSet 提供了多种构造函数,允许用户根据需求灵活创建实例。例如,使用 HashSet() 创建一个空 HashSet,或者通过 Collection 参数构造,实现与现有集合的合并。

       1.2 属性定义

       HashSet 主要属性包括容量(容量决定 HashMap 的大小)和负载因子(控制容量的扩展阈值),确保其高效存储和检索数据。

       二、操作函数

       2.1 add() - 向集合中添加元素,若元素已存在则不添加。

       2.2 size() - 返回集合中元素的数量。

       2.3 isEmpty() - 判断集合是否为空。

       2.4 contains() - 检查集合中是否包含指定元素。

       2.5 remove() - 删除集合中的指定元素。

       2.6 clear() - 清空集合,使其变为空。

       2.7 iterator() - 返回一个可迭代对象,用于遍历集合中的元素。

       2.8 spliterator() - 返回一个 Spliterator,用于更高效地遍历集合。

       三、HashSet 线程安全吗?

       3.1 线程安全解决

       HashSet 不是线程安全的,它不保证在多线程环境下的并发访问。为了确保线程安全,用户需要采用同步机制,如使用 Collections.synchronizedSet() 方法将 HashSet 转换为同步集合。同时,利用并发集合如 CopyOnWriteArrayList 和 ConcurrentHashMap 等,可以实现更高效、安全的并发操作。

本文地址:http://581.net.cn/news/78b282997092.html 欢迎转发