第十三届蓝桥杯决赛(国赛)真题 Java C 组【原卷】

文章目录 发现宝藏试题 A: 斐波那契与 7试题 B: 小蓝做实验试题 C: 取模试题 D: 内存空间试题 E \mathrm{E} E : 斐波那契数组试题 F: 最大公约数试题 G: 交通信号试题 I: 打折试题 J: 宝石收集 发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【宝藏入口】。 第十三届蓝桥杯大赛软件赛国赛 Java C 组 【考生须知】 考试开始后, 选手首先下载题目, 并使用考场现场公布的解压密码解压试题。 考试时间为 4 小时。考试期间选手可浏览自己已经提交的答案, 被浏览的答案允许拷贝。时间截止后,将无法继续提交或浏览答案。 对同一题目, 选手可多次提交答案, 以最后一次提交的答案为准。 选手必须通过浏览器方式提交自己的答案。选手在其它位置的作答或其它方式提交的答案无效。 试题包含 “结果填空” 和 “程序设计” 两种题型。 结果填空题: 要求选手根据题目描述直接填写结果。求解方式不限。不要求源代码。把结果填空的答案直接通过网页提交即可, 不要书写多余的内容。 程序设计题: 要求选手设计的程序对于给定的输入能给出正确的输出结果。考生的程序只有能运行出正确结果才有机会得分。 注意: 在评卷时使用的输入数据与试卷中给出的示例数据可能是不同的。选手的程序必须是通用的, 不能只对试卷中给定的数据有效。 所有源码必须在同一文件中。调试通过后,拷贝提交。 注意: 不要使用 package 语句。 注意:选手代码的主类名必须为: Main, 否则会被判为无效代码。 注意: 如果程序中引用了类库, 在提交时必须将 import 语句与程序的其他部分同时提交。只允许使用 Java 自带的类库。

【c++】继承学习(二):探索 C++ 中派生类的默认机制与静态成员共享

🔥个人主页:Quitecoder 🔥专栏:c++笔记仓 目录 `1.派生类的默认成员函数``2.继承与友元``3.继承与静态成员` 朋友们大家好,本篇文章我们来学习继承的第二部分 1.派生类的默认成员函数 来看下面的类: class Person { public: Person(const char* name = "jason") : _name(name) { cout << "Person()" << endl; } Person(const Person& p) : _name(p._name) { cout << "Person(const Person& p)" << endl; } Person& operator=(const Person& p) { cout << "Person operator=(const Person& p)" << endl; if (this != &p) _name = p._name; return *this; } ~Person() { cout << "~Person()" << endl; } protected: string _name; // 姓名 }; class Student : public Person { public: protected: int _num; //学号 }; Student对象生成的默认构造函数,对内置类型不做处理,对自定义类型调用它的默认构造函数,规则和以前一样

大数据Hadoop之——部署hadoop+hive+Mysql环境(Linux)

目录 前期准备 一、JDK的安装 1、安装jdk 2、配置Java环境变量 3、加载环境变量 4、进行校验 二、hadoop的集群搭建 1、hadoop的下载安装 2、配置文件设置 2.1. 配置 hadoop-env.sh 2.2. 配置 core-site.xml 2.3. 配置hdfs-site.xml 2.4. 配置 yarn-site.xml 2.5. 配置 mapred-site.xml 2.6. 配置 workers(伪分布式不配置) 2.7 配置sbin下启停命令 3、复制hadoop到其他节点(伪分布式不执行此步) 4、Hdfs格式化 5、启动hdfs分布式文件系统 三、msyql安装 1、卸载旧MySQL文件 2、Mysql下载安装 3、配置环境变量 4、删除用户组 5、创建用户和组 6、创建文件夹 7、更改权限 8、初始化 9、记住初始密码 10 将mysql加入到服务中 11、配置文件 12、设置开机启动并查看进程 13、 创建软连接 14、授权修改密码 四、HIve安装 1、下载安装 2、配置环境变量 3、配置文件 4、拷贝jar包 5、初始化 6、启动hive 前期准备 设置虚拟机 vi /etc/syscnfig/network-scripts/ifcfg-eth1 设置主机名 hostnamectl --static set-hostname 主机名 配置IP与主机名映射 vi /etc/hosts 关闭防火墙

JavaScript 垃圾回收机制深度解析:内存管理的艺术

🔥 个人主页:空白诗 文章目录 🎭 引言一、JavaScript内存模型与生命周期的深度解析📌 基本数据类型与栈内存的精妙运作📌 复杂数据类型与堆内存的广袤世界📌 生命周期管理的智慧与实践策略📌 WeakMap 和 WeakSet 介绍 二、垃圾回收机制(Garbage Collection, GC)的深度探索📌 引用计数法(Reference Counting)📌 标记-清除法(Mark-and-Sweep)📌 分代收集(Generational Collection) 三、垃圾回收的智能进化:增量标记与并发/并行回收📌 增量标记(Incremental Marking):小步快跑,减少卡顿📌 并发/并行回收:多手多脚,效率倍增📌 总结 四、内存泄漏防范手册:最佳实践指南1. 及时断开引用 —— 清理不再使用的对象2. 关注DOM引用 —— 解除事件监听与元素关联3. 定时器与回调管理 —— 控制异步资源4. 闭包中的变量 —— 精确管理作用域5. 模块与单例 —— 适度使用全局 六、面试考点1. JavaScript中垃圾回收机制的基本原理是什么?2. 什么是引用计数法?它的缺点是什么?3. 标记清除算法是如何工作的?为什么它能解决循环引用问题?4. 什么是分代收集?它如何提高垃圾回收的效率?5. 如何在JavaScript中避免内存泄漏? 七、总结 🎭 引言 在这个信息爆炸的时代,每一行代码都可能成为数字海洋中的璀璨星光,亦或是悄然累积的暗流。JavaScript,作为互联网世界的通用语言,它的每一次呼吸——数据的创建与消亡,都离不开垃圾回收机制的精密调控。在这篇文章中,我们将携手踏上一场深入JavaScript内存管理腹地的探险之旅,揭开垃圾回收机制那既神秘又强大的面纱,让每一次内存的分配与回收,都能成为推动应用高效运转的强劲动力。 一、JavaScript内存模型与生命周期的深度解析 📌 基本数据类型与栈内存的精妙运作 JavaScript内存管理的根基深植于栈内存与堆内存的双重架构之中。栈内存以其快速访问速度和严谨的生命周期管理著称,它主要承载着程序中的轻量级成员——基本数据类型,覆盖了数字number、字符串string、布尔值boolean、特殊标识undefined和null。栈内存的另一项重要职责是记录函数调用时的临时住客——局部变量和执行上下文,确保一旦函数执行完毕或变量走出了自己的作用范围,它们占用的内存空间就能迅速被释放,从而维护内存使用的高效率和及时周转。 let age = 25; // 为age在栈内存中分配空间,并储存数字25 function greet() { let message = "Hello!"; // greet执行期间,在栈内存为message分配临时住所 } greet(); // 函数演出结束,message占用的栈内存空间随即被回收 📌 复杂数据类型与堆内存的广袤世界 相较于栈内存的瞬时特性,堆内存如同一片广阔无垠的天地,为复杂数据类型如对象object、数组array以及函数(本质上作为对象存在)提供了一片生存的沃土。在这里,数据的家需要通过构造函数或字面量的方式显式建立。由于这些复杂结构可能被多个变量共享引用,甚至自身内部也包含引用关系,它们的生命周期管理就变得错综复杂,这也正是垃圾回收机制大展身手的舞台,负责甄别并清理那些已经孤立无援、不再被任何变量引用的内存区域。

本地搭建AI环境

本地搭建AI 这几天刚刚看到好兄弟分享的一段关于本地搭建AI的短视频,于是我按照视频里的讲解,进行了实践。感觉非常棒!!,马上整理成文字与大家分享一下。 在本地启动并运行大型语言模型,运行llama3、phi3和其他模型,自定义并创建您自己的。 安装Ollama 首先进入Ollama网站,在浏览器的地址栏输入:https://ollama.com/,直接进入网站,如下图所示: 根据你的操作系统,点击Download进行下载。 本人的操作系统是macOS,芯片是M3。下载之后,直接进行安装。 检验是否安装成功 输入 Ollama 命令,正常的得出命令行输出,表示已经安装成功,下面有 ollama 的常用命令 localhost:~ root# ollama Usage: ollama [flags] ollama [command] Available Commands: serve Start ollama create Create a model from a Modelfile show Show information for a model run Run a model pull Pull a model from a registry push Push a model to a registry list List models cp Copy a model rm Remove a model help Help about any command Flags: -h, --help help for ollama -v, --version Show version information Use "

Python版【植物大战僵尸 +源码】

文章目录 粉丝 专属:写在前面:功能实现环境要求怎么玩个性化定义项目演示:源码分享Map地图:Menubar.py主菜单 主函数:项目开源地址 粉丝 专属: 写在前面: 今天给大家推荐一个Gtihub开源项目:PythonPlantsVsZombies,翻译成中就是植物大战僵尸。 《植物大战僵尸》是一款极富策略性的小游戏。可怕的僵尸即将入侵,每种僵尸都有不同的特点,例如铁桶僵尸拥有极强的抗击打能力,矿工僵尸可以挖地道绕过种植在土壤表面的植物等。玩家防御僵尸的方式就是栽种植物。49种植物每种都有不同的功能,例如樱桃炸弹可以和周围一定范围内的所有僵尸同归于尽,而食人花可以吃掉最靠近自己的一只僵尸。玩家可以针对不同僵尸的弱点来合理地种植植物,这也是胜利的诀窍。游戏根据玩法不同分为五种游戏模式:冒险模式、迷你模式、解谜模式、生存模式、禅境花园。加之黑夜、屋顶、浓雾以及泳池之类的障碍增加了其挑战性。该游戏近乎永无止境。 功能实现 支持的植物:向日葵、豌豆射手、胡桃、雪豌豆射手、樱桃炸弹、三豌豆射手、大嘴花、puffshroom、马铃薯胺、穗状杂草、南瓜、胆小菇、墨西哥胡椒、阳光菇、冰川菇、催眠蘑菇。 支持僵尸:普通僵尸,旗帜僵尸,路障僵尸,铁桶僵尸,报纸僵尸。 支持在关卡开始时选择植物卡片。 支持白天级别、夜间级别、移动卡选择级别和胡桃保龄球级别。 环境要求 1、python3.7 注意: Python3.7是最佳运行环境,但是不是强制性要求。对于Linux: 如果你的 Linux 有预装的 Python3+ 就可以运行了。LINUX Mint 操作系统直接升级到 Python 3.7 有可能导致系统自带的 python 版本无法执行。 2、Python-Pygame 1.9 怎么玩 使用鼠标收集阳光,选择植物卡片并播种植物 您可以通过更改 source/constants.py 中的START_LEVEL_NUM值来设置起始级别 级别 1 和 2:天级别 第 3 级:夜间级别 第 4 级:移动卡片选择级别 5级:墙果保龄球级别 个性化定义 游戏的关卡数据,存储在json文件里的。具体目录:PythonPlantsVsZombies-master\source\data。我们可以进行自定义配置,例如僵尸的位置和时间,背景信息。 项目演示: 源码分享 Map地图: __author__ = 'marble_xu' import random import pygame as pg from .. import tool from .. import constants as c class Map(): def __init__(self, width, height): self.

Redis(主从复制搭建)

文章目录 1.主从复制示意图2.搭建一主多从1.搭建规划三台机器(一主二从)2.将两台从Redis服务都按照同样的方式配置(可以理解为Redis初始化)1.安装Redis1.yum安装gcc2.查看gcc版本3.将redis6.2.6上传到/opt目录下4.进入/opt目录下然后解压5.进入 redis-6.2.6目录6.编译并安装7.进入 /usr/local/bin 查看是否有redis的命令 2.启动并使用Redis1.进入 /opt/redis-6.2.6/2.将里面的redis.conf复制一份到/etc下3.编辑 /etc/redis.conf,将daemonize no修改成daemonize yes即以守护进程的方式启动(后台启动)4.启动redis,指定刚才的配置文件5.查看redis进程 3.Redis基本配置1.修改端口为7489 port2.设置redis密码 requirepass3.使redis支持远程访问 bind4.登录redis的命令行,关闭redis5.重新启动redis,使配置生效 4.开启7489端口1.宝塔开启端口2.腾讯云开启端口(只允许本机ip访问) 5.Redis持久化配置1.进入redis配置文件2.dbfilename为redis持久化的文件名(一般不用改)3.dir修改为/root/则每次持久化的dump.rdb都会在/root/下,恢复时无论在哪里启动,都会读取这个文件进行恢复4.开启AOF持久化配置,编辑配置文件找到appendonly,设置成yes5.进入命令行关闭redis,需要指定端口登录6.重新启动redis,使配置生效7.发现/root/下面有两个配置文件,如果没有dump.rdb是因为没有对redis进行操作 6.测试Java连接redis1.引入jedis的jar包2.编写测试程序 3.配置Redis的一主二仆1.在配置之前,将三台的Redis的7489端口完全放开2.三台机器都进入redis的客户端,将数据全部清除3.输入 info replication 可以看到目前三台机器都为master4.在两台从服务上输入 slaveof 主服务ip 主服务端口 来设置主服务5.输入 info replication 来查看角色1.从服务2.主服务3.没连接成功,后来询问GPT4发现如果主服务器配置了密码,则需要在从服务器的masterauth 中设置一下密码 6.为两台从服务器的 masterauth 配置主服务器的密码,然后测试连接1.分别设置密码2.分别重启3.从服务器重新配置4.再查看一下主服务器的状态,也是成功连接两台从服务器 7.注意事项和细节1.如果想要持久化,需要在从服务的配置文件中配置 slaveof ...... 否则重启主从关系就会消失2.主服务器可读可写,从服务器只可读 3.主从复制原理分析1.原理示意图2.解读3.细节1.主服务down掉了的情况2.当从服务down掉了的情况 4.薪火相传5.反客为主(是在薪火相传的基础上的) 4.哨兵模式(sentinel)1.配置哨兵1.**保持一主二仆的环境即可**2.随便找一台服务器启动哨兵,这里选择在master服务器启动1.在/etc下面创建一个sentinel.conf的配置文件2.编辑文件,设置master的名字,ip+端口以及哨兵的个数,这里是1,还有master的密码3.再开启一个连接,启动哨兵,指定配置文件 2.测试1.关闭master2.等待一会,查看哨兵,可以看到切换了master3.查看子节点的情况,注意:此时需要重新进行密码验证4.重启原来的master,会自动降级为子节点 3.注意事项和细节1.主机down后的执行流程2.哨兵挑选新master的依据3.重启原来的master,会自动降级为子节点4.如果原来的主节点有密码,则需要在sentinel.conf 配置auth-pass参数设置密码5.关于密码配置方案 1.主从复制示意图 2.搭建一主多从 1.搭建规划三台机器(一主二从) 2.将两台从Redis服务都按照同样的方式配置(可以理解为Redis初始化) 1.安装Redis 1.yum安装gcc yum install gcc 2.查看gcc版本 gcc --version 3.将redis6.2.6上传到/opt目录下 4.进入/opt目录下然后解压 cd /opt && tar -zxvf redis-6.2.6.tar.gz 5.进入 redis-6.2.6目录 cd redis-6.2.6 6.编译并安装 make && make install 7.

【Linux】线程的内核级理解&&详谈页表以及虚拟地址到物理地址之间的转化

一、线程的概念 对于进程来说,进程创建时间和空间成本较高,因为进程是承担分配系统资源的基本实体,所以线程的出现就成为了必然。Linux线程与进程非常相似,Linux设计者在设计之初觉得如果再为线程设计数据结构和调度算法就会使整个系统变得十分复杂。地址空间和地址空间上的虚拟地址,本质就是一种资源,所以线程就在进程的基础上让不同的线程看到进程地址空间上的代码区中的不同代码,并让不同线程去执行不同的代码,这样同样也实现了线程的功能。不同的线程在同一个进程地址空间中运行,共享相同的内存和其他资源。所以说线程是进程内部的一个执行分支,线程也是CPU调度的基本单位。 每个线程都有一个与之关联的task_struct结构体,该结构体包含了线程的状态信息、调度信息、资源使用情况等。CPU在执行调度的时候,根本就不用区分进程和线程,反正你们都有task_struct结构体,都是执行流。Linux中所有的可调度执行流都叫做轻量级进程。 二、详谈页表以及虚拟地址到物理地址之间的转化 磁盘中的数据块和内存中的数据块都是4kb大小。为了管理内存中每一块4kb大小的内存块,操作系统内核中会有描述该内存块的结构体,4GB的内存大小中就有1048576个内存块,再利用数组就能将整个内存管理起来,对于内存的管理就变成了对于数组的增删查改。所以,操作系统进行内存管理的基本单位就是4kb。 再谈页表,其实页表并不是只有一块数据结构,而是分为了页目录,页表。一个虚拟地址有32位,32位中的前10位用来表示处于页目录中的哪一个位置,页目录中最多可以存放个页表的首地址,第11到20位用来表示处于页表的哪一个页表项,一个页表中最多也有个页表项,一个页表项就对应内存中的一个4kb大小的数据块。最后12位用来确定数据块中的字节,刚好就是4kb,正好可以确定是哪一个字节,所以后12位也叫做页内偏移。 如果再在页表项中加入访问权限审查,有没有被使用过等等标志位,就能对用户操作进行一些审查以及拦截,来保证内存访问的安全性。 针对页表的这一种分页存储的模式,我们所写的函数编译完就是一块一块的虚拟地址,根据函数名就可以找到函数入口地址,各个函数就分配得到了不同的虚拟地址,也就是得到了不同的页表区域。同样的,我们只要给不同的线程分配不同的页表区域,就可以让不同的线程能够访问到页表的不同子集,进一步的,就可以让不同的线程访问到不同的代码,从而实现多线程技术。 三、创建线程的小例子 thread:这是一个指向pthread_t类型的指针,用于获取新创建线程的线程ID。在调用pthread_create后,这个指针会被设置为新线程的ID。 attr:这是一个指向pthread_attr_t类型的指针,用于设置线程的属性,如栈大小、优先级等。如果这个参数为NULL,那么线程将使用默认的属性。通常情况下,如果你不需要设置特殊的线程属性,可以传递NULL。 start_routine:这是一个函数指针,指向线程开始执行时要调用的函数。这个函数通常被称为线程的“入口点”或“启动例程”。 arg:用于向线程的启动例程传递参数。你可以通过这个参数向线程传递任何类型的数据。如果你的启动例程不需要任何参数,可以传递NULL。 3.1、主函数 #include <iostream> #include <unistd.h> #include <pthread.h> using namespace std; void* newthread(void*) { while (true) { cout << 22222222 << endl; sleep(1); } } int main() { pthread_t pthread; pthread_create(&pthread, nullptr, newthread, nullptr); while(true) { cout << 11111111 << endl; sleep(1); } return 0; } 3.2、makefile myThread:testThread.cc g++ -o $@ $^ -std=c++11 -lpthread .PHONY:clean clean: rm -f myThread 可以看到两个线程就同时跑起来了: 

[MySQL数据库] Java的JDBC编程(MySQL数据库基础操作完结)

🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343 🏵️热门专栏:🍕 Collection与数据结构 (91平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482 🧀Java EE(94平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482 🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482 感谢点赞与关注~~~ 目录 1. Java的数据库编程-----JDBC2. JDBC工作原理2.1 JDBC的访问数据库层次结构:2.2 JDBC的优势: 3. JDBC的使用3.1 导入JDBC的.jar文件3.2 JDBC编程基本步骤 1. Java的数据库编程-----JDBC 在数据库的编程中,由于各个数据库的编程方式各不相同,所以在市场上流行着很多数据库,这就成为了程序员们非常头疼的一个点,于是这时候就需要一个人来统一天下,于是Java老大哥便站了出来.每一种数据库都需要给Java语言提供一个API,把原生的API进行封装,按照Java的规定统一过来.JDBC,即Java Database Connectivity,java数据库连接.是一种用于执行SQL语句的Java API,它是Java中的数据库连接规范.这个API由java.sql.*,javax.sql.*包中的一些类和接口组成,它为Java开发人员操作数据库提供了一个标准的API,可以为多种关系数据库提供统一访问. [注释] 什么是API: API(Application Progromming interface 应用程序编程接口),就可以理解为一组"类",或者是"接口",有的库API非常多,就形成了SDK(软件开发工具包),例如:jdk. 2. JDBC工作原理 JDBC为多种关系型数据库提供了统一的访问方式,作为特定数据库厂商访问API的一种高级抽象,他主要包含一些通用的接口类. 2.1 JDBC的访问数据库层次结构: 这里的数据库JDBC驱动程序是数据库提供的"接口转换程序",通过驱动程序把数据库原生的应用程序编程接口和Java的应用程序编程接口转接过来,就可以理解为我们常用的转接头. 2.2 JDBC的优势: 开发数据库应用不受特定数据库厂商API的限制.应用程序的可移植性大大增强.Java语言访问数据库操作完全面向抽象接口编程. 3. JDBC的使用 首先我们需要下载JavaJDBC编程的第三方库,把Java和MySQL建立联系.这里我们从"中央仓库"中即可下载. JDBC下载地址:https://mvnrepository.com/artifact/mysql/mysql-connector-java/5.1.49 下载好了之后,我们就会得到一个后缀名为.jar的文件.此时我们就可以建立连接了. 3.1 导入JDBC的.jar文件 首先我们新建一个项目,在根目录下新建一个目录.命名为lib. 之后我们把.jar文件导入该目录中. 之后右键.jar文件,选择"添加为库". 3.2 JDBC编程基本步骤 在导入成功之后,我们就可以开始编程了. 首先创建数据源 DataSource dataSource = new MysqlDataSource(); ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource) dataSource).setUser("root"); ((MysqlDataSource) dataSource).setPassword("qwe123524"); 第一行就是让数据库厂商与JDBC进行对接,就是让数据库厂商实现JDBC中提供的提供的interface,进一步实现其中约定好的抽象方法. 下一行就是固定的写法,直接照抄. 之后就是输入用户名,用户名默认为"root". 下一行就是该用户登录数据库的密码.

Spring Web MVC 快速入门

🎥 个人主页:Dikz12🔥个人专栏:Spring学习之路📕格言:吾愚多不敏,而愿加学欢迎大家👍点赞✍评论⭐收藏 目录 什么是Spring MVC? MVC模式介绍 ​编辑学习Spring MVC 建立连接 @RequestMapping 使⽤ ​编辑实战练习 加法计算器 用户登录 接口定义 什么是Spring MVC? 官方描述: 来自:Spring Web MVC :: Spring Framework 翻译为中文: Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring框架中。正式名称“Spring Web MVC”来自其源模块的名称( spring-webmvc ),但它更常被称“Spring MVC”。 MVC 是⼀种架构设计模式, 也⼀种思想, ⽽ Spring MVC 是对 MVC 思想的具体实现. 除此之外, Spring MVC还是⼀个Web框架. 所以,, Spring MVC 是⼀个实现了 MVC 模式的 Web 框架. MVC模式介绍 MVC 是 Model View Controller 的缩写,它是软件⼯程中的⼀种软件架构设计模式,它把软件系统分 为 模型、视图和控制器 三个基本部分. View(视图)指在应⽤程序中专⻔⽤来与浏览器进⾏交互,展⽰数据的资源. Model(模型)是应⽤程序的主体部分,⽤来处理程序中数据逻辑的部分.Controller(控制器)可以理解为⼀个分发器,⽤来决定对于视图发来的请求,需要⽤哪⼀个模型来处理,以及处理完后需要跳回到哪⼀个视图。即⽤来连接视图和模型. 不过Spring在实现MVC时,也结合⾃⾝项⽬的特点,做了⼀些改变,相对⽽⾔,下⾯这个图或许更加合适.(前后端分离) 学习Spring MVC 学习SpringMVC,重点也就是学习如何通过浏览器和⽤⼾程序进⾏交互.

【C++】string类的使用①(默认成员函数 || 迭代器接口begin,end,rbegin和rend)

🔥个人主页: Forcible Bug Maker 🔥专栏: STL || C++ 目录 前言🌈关于string类🌈string类的成员函数🔥默认成员函数==string类对象的构造(constructor)====string类对象的析构====string类对象的赋值运算符重载== 🔥迭代器接口(iterators)==begin====end====rbegin====rend====cbgin,cend,erbegin和crend== 结语 前言 本篇博客主要内容:STL库中string类的默认成员函数和各种迭代器接口的介绍和使用。 在开始我们string类使用接口的讲解之前,想先讲讲为什么我们要学习string类。在C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。 简单说,string就是C++STL标准库中便于维护和操作字符串的一个类。 学习STL过程中,我们主要参考这个网站中的文档:https://cplusplus.com,虽然里面的内容是全英的,但是不用担心,我会带着大家一一去翻译并讲解其中的接口。 🌈关于string类 字符串是表示字符序列的类。 标准的字符串提供了此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。 string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(关于模板更多的信息,请参考basic_string)。 请注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。 对以上文字做一个总结: string是表示字符串的类该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。string类再底层实际是:basic_string模板类的别名,typedef basic_string<char,char_traits,alloctor> string;不能操作多字节或变长字节的序列。 在使用string类时,必须包含相应头文件#include<string>以及using namespace std; 🌈string类的成员函数 C++STL库的string类中重载的成员函数非常之多,但并不是每个接口都有着其必要性。string类是C++中最先被开发和实验的类,由于向前兼容等各种原因,其实其中也不免存在一些函数的冗余,在上百个重载的接口中,真正常用的也就是那十几二十个。对于一些相同道理的重载,我会做简单解释而不会展开讲,避免文章内容的冗余。 🔥默认成员函数 string类对象的构造(constructor) string类提供了七种方式的重载用于构造string类对象。 (1)无参构造(默认构造) string(); 构造出一个空的string,里面存储0个字符元素。 (2)拷贝构造 string(const string& str); 构造出一个和str对象内容相同的拷贝对象。 (3)字串构造 string (const string& str, size_t pos, size_t len = npos); 拷贝str从pos位置开始跨越len个长度的元素到新创建的对象中(如果字符串太短或未提供第三个参数,直接从pos位置拷贝到字符串的末尾)。 (4)通过字符串构造 string (const char* s); 通过s指向的以 空字符(‘\0’) 结尾的字符串创建新的string类型的对象。 (5)通过部分字符串构造 string (const char* s, size_t n);

【Java】Java基础 使用集合实现斗地主分牌

📝个人主页:哈__ 期待您的关注 目录 0.思路 1.创建玩家手牌集合 2.创建牌堆 3. 把牌放入牌堆 4.洗牌 5.进行分牌 6.完整代码 今天使用集合TreeSet来实现一个斗地主的分牌流程。 TreeSet集合的一个特点就是 元素有序,这样就方便我们分的牌自动排序。 0.思路 1.创建玩家手牌集合 我们到时候分的牌都存储在这里,但你可能会有疑问,因为存储的泛型是Integer,但扑克牌是有花色的,这该如何实现? TreeSet<Integer> zhangsan=new TreeSet<Integer>(); TreeSet<Integer> lisi=new TreeSet<Integer>(); TreeSet<Integer> wangwu=new TreeSet<Integer>(); TreeSet<Integer> dipai=new TreeSet<Integer>(); 2.创建牌堆 我们创建了一个名为poke的HashMap结构,poke用来存储我们的扑克,而poke的key是每一张牌的一个id,value就是具体的牌。 HashMap<Integer,String>poke=new HashMap<Integer,String>(); String[] color={"♦","♣","♥","♠"}; String[] number={"3","4","5","6","7","8","9","10","J","Q","K","A","2"}; 我们到时候洗牌的时候,洗的是这些id,但是并不是直接在poke中洗,poke的作用只是记录我们有哪些牌。所以 我们在创建一个用来洗牌的数组,并把所有的id放入。 ArrayList<Integer> xipai=new ArrayList<Integer>(); 3. 把牌放入牌堆 遍历我们的String数组,把花色和牌号组合一下并放入poke中,同时把poke中的key放入我们的洗牌集合中。最后不要忘了大小王。 int index=0; for(String Number:number){ for(String Color:color){ String POKE=Color+Number; poke.put(index,POKE); xipai.add(index); index+=1; } } poke.put(52,"小王"); poke.put(53,"大王"); xipai.add(52); xipai.add(53); 4.洗牌 一行代码即可,使用Collecitons自带的数组打乱方法。 Collections.shuffle(xipai); 5.进行分牌 如果只剩下最后三张了,就直接放入到我们的底牌集合当中,否则的话就进行模3取余操作进行判断应该分给谁。 for(int i=0;i<xipai.size();i++){ if(i>=xipai.

c语言常用操作符(2)

1.移位操作符 移位操作符分为<<左移操作符和右移操作符>> 注:移位操作符的操作数只能是整数,同时移位操作符移动的是存储在内存中的二进制位(也就是补码) 同时移位操作符不要移动负数位,这个是标准未定义的。 1.<<操作符 移位规则:左边抛弃、右边补0 例1 #include<stdio.h> int main() { int a=10; int b=a<<1; printf("a=%d\n",a); printf("b=%d\n",b); return 0; } 由于a为正整数,所以补码与原码相同 所以b输出结果为20 例2 #include<stdio.h> int main() { int a = -1; int b = a << 1; printf("a=%d\n", a); printf("b=%d\n", b); return 0; } 由于a为负整数,所以补码等于原码取反加一 所以输出b输出结果为-2 由以上例1与例2可以发现左移操作符有乘2的效果 2.>>操作符 在右移操作符不同于左移操作符,右移操作符有两种运算 1. 逻辑右移:左边用0填充,右边丢弃 2. 算术右移:左边用原该值的符号位填充,右边丢弃 例1 #include<stdio.h> int main() { int a = -1; int b = a >> 1; printf("a=%d\n", a); printf("

c++笔记——概述运算符重载——解析运算符重载的难点

前言:运算符重载是面向对象的一个重要的知识点。我们都知道内置类型可以进行一般的运算符的运算。但是如果是一个自定义类型, 这些运算符就无法使用了。那么为了解决这个问题, 我们的祖师爷就在c++中添加了运算符重载的概念。 本篇主要通过实例的实现来讲述了运算符重载的知识点。 目录 运算符重载的应用 运算符重载的定义 赋值运算符重载 流提取和流插入 const问题 定义位置的问题 运算符重载的应用 首先, 先了解以下运算符重载能做些什么,先看下面这张图 在这张图中, 红框框是我定义的一个自定义类型。 这个自定义类型的成员包括了string类型的_name。 int类型的_age.它代表的就是一个人的类型。 每一个类的实例化对象都有他们的姓名, 也有他们的年龄。 那么很显然, 它的实例化对象也可以进行年龄的加法,也就是增长年龄。 所以, 绿色箭头指向的位置, 如果我的本意是想要让实例化对象p1的_age加2, 也就是p1这个实例化对象的年龄增加了2。但是很显然, 这个运算对于+这个运算符来说, 是做不到的, 因为对于运算符来说, 他们默认只能处理内置类型, 而不能处理自定义类型。 这里如果想要处理自定义类型, 就需要使用我们的运算符重载, 运算符重载的目的就是为了让一个运算符可以处理自定义类型的运算。 如下是我重载的peo类的一个加法运算符。 //这里我将整个类搬过来方便观察。 struct peo { string _name; int _age; //默认构造, 这里是默认构造, 因为每一个参数都有缺省, 那么这个就是一个默认构造函数 peo(string str = string(), int age = 0) :_age(age) { _name = str; } //定义的peo类的加法运算 peo operator+(const int x) { peo tmp = *this; tmp.

一文彻底学会Vue3路由:全面讲解路由流程、路由模式、传参等——全栈开发之路--前端篇(7)路由详解

全栈开发一条龙——前端篇 第一篇:框架确定、ide设置与项目创建 第二篇:介绍项目文件意义、组件结构与导入以及setup的引入。 第三篇:setup语法,设置响应式数据。 第四篇:数据绑定、计算属性和watch监视 第五篇 : 组件间通信及知识补充 第六篇:生命周期和自定义hooks 本文将带你从头到尾将Vue3中的路由学透,学完之后所有的跳转需求都可以实现。 文章目录 路由一、路由基础实践——流程梳理1.index.ts2.三个页面组件的vue3.main.ts4.app.vue5.自定义路由名效果展示 二、路由模式1.history模式2.hash模式3.模式使用推荐 三、嵌套路由1.基本嵌套2.路由传参1.query参数a)基本写法b)对象快速写法 2.params参数1.基本写法2.快捷写法 3.路由的props配置 四、编程式导航(重要)脚本操作跳转五、补充1.replace属性2.重定向 路由 路由可以实现页面的跳转,可以用来实现SPA应用(单页面应用) 类似这种,左边导航,右边展示,全程画面不抖动,不跳转。 点击导航,路径(网址)发生变化,路由器捕获,卸载当前组件,挂载新的组件,这些组件都是一个一个Vue文件写的页面。 一、路由基础实践——流程梳理 我们先安装路由 npm i vue-router,再在src下创建router文件夹。 1.index.ts 我们在router中创建index.ts,这个文件的意义在于创建一个路由器,并将之暴露出来。 import { createRouter } from "vue-router" import home from "@/components/home.vue"; import dog from "@/components/dog.vue"; import cc from "@/components/cc.vue"; //创建路由器 const router = createRouter({ //管理路由 routes:[ //一个一个的路由规则 { //路径 path:'/home', //组件绑定 component:home }, { //路径 path:'/dog', //组件绑定 component:dog }, { //路径 path:'/test', //组件绑定 component:cc } ] }) export default router 请仔细查看写在代码旁的注释,这里做一个大致说明,这个地方是要进行一个路由的绑定,我们先在src/components中新建三个文件,这三个文件就是之后我们可以用来切换的页面Vue文件

【小黑送书—第二十期】>>K邻算法:在风险传导中的创新应用与实践价值(文末送书)

01 前言 在当今工业领域,图思维方式与图数据技术的应用日益广泛,成为图数据探索、挖掘与应用的坚实基础。本文旨在分享嬴图团队在算法实践应用中的宝贵经验与深刻思考,不仅促进业界爱好者之间的交流,更期望从技术层面为企业在图数据库选型时提供新的视角与思路。 02 K邻算法的实践意义 K邻算法(K-Hop Neighbor),即K跳邻居算法,是一种基于广度优先搜索(BFS)[1] 的遍历策略,用于探索起始节点周围的邻域。该算法在关系发现、影响力预测、好友推荐等预测类场景中得到了广泛应用。 在图论中,沿着一条边移动被视为一跳(hop)。在遍历图中的顶点时,我们需要考虑多跳问题。图论起源于数学家欧拉在1836年提出的哥尼斯堡七桥问题,它奠定了图计算的数学基础。自20世纪80年代以来,图计算技术迅速发展,成为现代计算领域的重要组成部分。 在现实世界中,危机的传播正是K邻搜索的一个典型应用。以发生危机的实体为起点,顺着或逆着(取决于边的具体定义)边的方向进行1步、2步、3步乃至更深层次的查询,得到的就是先后会被危机波及到的实体。 03 创新应用与案例分析 以某知名房地产企业HD的供应链图谱为例,我们可以通过持股方向、资金流向等信息,清晰直观地揭示危机的传播路径和传递对象。 以HD为例,危机发生后,风险传播路径如下: 第一层:影响HD的关联公司; 第二层:影响公司员工和供应商; 第三层:影响购房者(供应商停止供货、工人停工,可能导致HD的在建工程停滞)。 …… 风险从HD集团开始,逐步扩散至关联公司、员工、供应商、购房者等,形成了一张复杂的“网络”,呈现出明显的“链条效应”。 然而,许多与风险传导相关的实际应用并未采用图计算,而是依赖于手工计算,如银行KYC部门在计算UBO时仍使用Excel表。这种做法的效率和准确率可想而知。这与金融机构IT系统的陈旧和工作方法的落后有直接关系,阻碍了业务的开展,如企业影响力分析。 企业影响力分析不仅涉及持股关系、生产供求关系等传统问题,还应包括与企业相关的所有金融行为和事件,以及与这些行为事件直接或间接相关的事务。分析的视角不应仅限于企业实体,而应扩展至企业发布的产品、债券等。 如图3所示,分析的核心是企业的某个债券,其价格下跌可能直接影响其他债券的价格: 图4则标出了持有该债券的、可能受影响的省内其他企业: 图3和图4展示的是该债券的1步邻居,从这些邻居继续向外探寻就能得到该债券价格下跌后产生的危机传递效应,如图5所示: 专家们已越来越认识到,金融风险并不是孤立存在的,不同风险间具有链条效应,任何一只蝴蝶扇动翅膀,都有可能造成跨市场的风险传染——风险的关联性具有相互转化、传递和耦合的特点——图技术与蝴蝶效应在本质上是不谋而合的,即通过深度挖掘不同来源的数据,以网络化分析的方式去洞察。 此外,金融场景是一种基于长链条计算的场景,这就导致技术实现时的规则更为复杂,因为会涉及到各种回溯、归因,而且数据的计算量更大,同时也更注重时效性。只有实现真正的实时、全面、深度穿透、逐笔追溯、精准计量的监测和预警,才能保障金融风控中不会出现“蝴蝶效应”式的风险发生。 值得注意的是,图往往包含着复杂的属性及定义,例如:边的有向、无向,边的属性权重,K 邻是否包含 K-1 邻,如何处理计算环路等等,这些问题会导致 K 邻算法具体实现的差异。此外,在一些实际场景中,图自身拓扑结构的变化,过滤条件的设定,节点、边属性的变化都会影响到 K 邻计算的结果。 在行业应用中,K邻算法通常应用于多模态的异构图,即将多个单一信息的图融合在一起形成的综合性图谱。这对算法实现者的数据收集和构图能力提出了高要求,同时也对K邻算法的灵活性和功能性提出了更高标准。嬴图的高密度并发图算法库是目前全球运行最快、最丰富的图算法集合,支持通过EXTA接口进行热插拔和扩展。 如果在公开资料中看到K邻算法的应用多是同构图(只有一种点、一种边),可能是因为作者想通过简单的例子阐明观点,或者因为构图能力不足限制了算法的应用,也可能是K邻算法的实现不尽人意,无法对异构图进行恰当处理。K邻算法的应用应该是广泛且实际的,能够解决现实问题的,如果是因为后面两种情况而限制了算法的“大展宏图”,那么相关图厂商就应该反思一二并提高自身了! 最后,一个优秀的算法设计不仅应具备解决问题的能力,还应关注计算效率,即算力。我们列举了一些高性能图计算系统应具备的核心能力,以供企业在评估市场上各种图计算产品时作为参考: 高速图搜索能力:高QPS/TPS、低延时,实时动态剪枝能力; 对任何规模图的深度、实时搜索与遍历能力(10层以上); 高密度、高并发图计算引擎:极高的吞吐率; 成熟稳定的图数据库、图计算与存储引擎、图中台等; 可扩展的计算能力:支持垂直与水平可扩展; 3D+2D高维可视化、高性能的知识图谱Web前端系统; 便捷、低成本的二次开发能力(图查询语言、API/SDK、工具箱等)。 K邻算法:在风险传导中的创新应用与实践价值 推荐语:这是一本全面讲解当下主流图算法原理与工程实践的著作,旨在帮助读者在分析和处理各种复杂的数据关系时能更好地得其法、善其事、尽其能。本书概念清晰、内容丰富、实用性强、语言流畅,深入浅出、重点突出,既适合入门读者阅读,又适合有一定图数据库基础的进阶人员阅读。 送书活动 🎁文末福利(切记关注+三连,否则抽奖无效) 🎁本次送书1~4本【取决于阅读量,阅读量越多,送的越多】👈⌛️活动时间:截止到2024-5-15 10:00✳️参与方式: 关注博主+三连(点赞、收藏、评论)🏆🏆 抽奖方式: 评论区随机抽取小伙伴免费包邮送出!!

一个账号玩遍ChatGPT/Claude-3/Midjourney 省钱又省力

当 OpenAI 的闭源 GPT-4 和 Meta 的开源 LLaMA 3 70B 模型在 Chatbot Arena Elo Score、MMLU 和 MT Benchmark 测试中表现出相当的性能时,选择更昂贵的专有模型(其成本高出 58 倍)的论据是: NVIDIA GPU Inference 上的运行速度比 Groq LPU Inference 上的 LLaMA 慢 17 倍,并且变得越来越难以制作 我发现 Llama 3 70B 和 GPT-4 之间存在巨大差异。但可能就像音质一样。如果有一款耳机的音质比目前最好的耳机高出 100 倍,几乎没有人会听出​​差别。 OpenAI 首席运营官 Brad Lightcap 表示,像今天这样的生成式人工智能在一年内将变得“糟糕得可笑”。 ChatGPT 很快就会承担更多“复杂的工作”并成为“伟大的队友”。先是 Sama,现在是 Brad,为什么不直接发布 GPT-5 如果“我”可以做到这一点- OpenAI、Claude-3、Midjourney 等…您也可以做到这一点 - 可能比我更好 这是一个非常有用的功能,包含在 ChatGPT、Claude-3、Midjourney 等,而不至于每个都需要去开通PLUS

【算法】基础算法004之前缀和

👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》《Linux》《算法》 🌝每一个不曾起舞的日子,都是对生命的辜负 前言 本篇文章为大家带来前缀和算法,前缀和算法可以以O(1)的时间复杂度快速求出某一段连续区间的和,这个连续区域既可以是一维的也可以是二维的。 欢迎大家📂收藏📂以便未来做题时可以快速找到思路,巧妙的方法可以事半功倍。 ========================================================================= GITEE相关代码:🌟樊飞 (fanfei_c) - Gitee.com🌟 ========================================================================= 1.⼀维前缀和 【模板】前缀和_牛客题霸_牛客网 (nowcoder.com)https://www.nowcoder.com/practice/acead2f4c28c401889915da98ecdc6bf?tpId=230&tqId=2021480&ru=/exam/oj&qru=/ta/dynamic-programming/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D196 前缀和:可以快速求出某一段连续区间的和。 本道题目如果使用暴力计算的话会超时,所以需要进行优化。 前缀和解题模板 第一步:预处理出来一个前缀和数组,比如本题dp[i]表示1-i区间内所有元素的和,且dp[i]=dp[i-1]+arr[i];第二步:使用前缀和数组,比如本题求[l,r]区间元素的和就是dp[r]-dp[l-1]; #include <iostream> #include <vector> using namespace std; int main() { // 1.输入数据 int n,q; cin>>n>>q; vector<int> arr(n+1); for(int i=1;i<=n;i++) cin>>arr[i]; // 2.预处理出来一个前缀和数组 vector<long long> dp(n+1); for(int i=1;i<=n;i++) dp[i]=dp[i-1]+arr[i]; // 3.使用前缀和数组 int l,r; while(q--) { cin>>l>>r; cout<<dp[r]-dp[l-1]<<endl; } return 0; } 注意: 防止溢出,所以dp数据类型选用long long;多开一个空间(n+1)是为了防止越界,因为最后需要[l-1],所以下标一般都是以1为起始。 2.二维前缀和 【模板】二维前缀和_牛客题霸_牛客网 (nowcoder.com)https://www.nowcoder.com/practice/99eb8040d116414ea3296467ce81cbbc?tpId=230&tqId=2023819&ru=/exam/oj&qru=/ta/dynamic-programming/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D196 同样的我们使用前缀和解题模板: 第一步:预处理出来一个前缀和数组,本题中dp[i][j]表示[1,1]-[i][j]区间内所有元素的和。第二步:使用前缀和数组。 首先如何得到状态转移方程,即dp[i][j]如何计算? 如图所示:

【MsSQL】数据库基础 & 库的基本操作

目录 一,数据库基础 1,什么是数据库 2,主流的数据库 3,连接服务器 4,服务器,数据库,表关系 5,使用案例 二,库的操作 1,创建数据库 2,创建数据库案例 3,字符集和校验规则 1,查看系统默认字符集以及校验规则 2,查看数据库支持的字符集 3,查看数据库支持的字符集校验规则 4,校验规则对数据库的影响 4,操纵数据库 1,查看数据库 2,显示创建语句 3,修改数据库 4,数据库删除 5,备份和恢复 1,备份 2,还原 3,注意事项 6,查看连接情况 一,数据库基础 1,什么是数据库 存储数据用文件就可以了,为什么还要弄个数据库? 文件保存数据有以下几个缺点: 文件的安全性问题 文件不利于数据查询和管理 文件不利于存储海量数据 文件在程序中控制不方便 数据库存储介质: 磁盘 内存 为了解决上述问题,专家们设计出更加利于管理数据的东西——数据库,它能更有效的管理数据。数据库的水平是衡量一个程序员水平的重要指标。 2,主流的数据库 SQL Sever: 微软的产品,.Net程序员的最爱,中大型项目。 Oracle: 甲骨文产品,适合大型项目,复杂的业务逻辑,并发一般来说不如MySQL。 MySQL:世界上最受欢迎的数据库,属于甲骨文,并发性好,不适合做复杂的业务。主要用 在电商,SNS,论 坛。对简单的SQL处理效果好。 PostgreSQL :加州大学伯克利分校计算机系开发的关系型数据库,不管是私用,商用,还是学术研究使用,可 以免费使用,修改和分发。 SQLite: 是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它的设 计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可 能只需要几百K的内存就够了。 H2: 是一个用Java开发的嵌入式数据库,它本身只是一个类库,可以直接嵌入到应用项目中。 3,连接服务器 输入: mysql -h 127.0.0.1 -P 3306 -u root -p 一般我们用 mysql -u root -p 就可以了

算法学习:数组 vs 链表

🔥 个人主页:空白诗 文章目录 🎯 引言🛠️ 内存基础什么是内存❓内存的工作原理 🎯 📦 数组(Array)📖 什么是数组🌀 数组的存储📝 示例代码(go语言)🎯 执行增加操作🎯 执行删除操作 📊 优缺点分析 🔗 链表(Linked List)📖 什么是链表🌀 链表的存储📝 示例代码(go语言)📊 优缺点分析 📊 数组与链表的对比🎯 访问速度🎯 插入与删除效率🎯 空间利用效率🎯 应用场景 📚 小结 🎯 引言 在编程的奇妙世界里,数组和链表作为两种基础且重要的数据结构,各自扮演着不可替代的角色。它们在存储和管理数据方面展现出了不同的优势和局限。本文将带领你深入了解数组(Array)与链表(Linked List)的奥秘🚀 🛠️ 内存基础 什么是内存❓ 内存,尤其是随机存取存储器(RAM),是计算机中用于临时存储数据和程序指令的部分。与硬盘相比,内存访问速度快,但信息非持久保存。 想象一下,当你在解决一个复杂的算法问题时,那些数字、字符,乃至复杂的数据结构,都需要一个地方暂时停留和操作——这个地方就是内存 内存的工作原理 🎯 内存由一系列连续或非连续的存储单元组成,每个单元都有一个独一无二的地址。通过地址,CPU(中央处理器)可以迅速找到所需的数据。 就好比内存是一个储物柜,你将东西放进去后会给你一个号码,通过号码你可以快速找到你存储物品的柜子。 需要将数据存储到内存时,你请求计算机提供存储空间,计算机给你一个存储地址。需要存储多项数据时,有两种基本方式——数组和链表。 📦 数组(Array) 📖 什么是数组 数组是一种线性数据结构,它将元素按照一定的顺序存储在一块连续的内存区域中。每个元素都有一个索引(从0开始),通过索引可以快速访问数组中的任意元素。但是对于插入和删除,特别是当位置不在末尾时,可能需要移动后续的所有元素,以保持连续性,导致最坏情况下的时间复杂度为O(n)。 +---+---+---+---+ | 1 | 2 | 3 | 4 | +---+---+---+---+ ^ ^ | | 索引0 索引3 🌀 数组的存储 数组在创建时会一次性申请足够的内存空间进行存储。这意味着数组的大小是固定的,一旦声明,不能轻易改变。