PTA题解 --- 阶梯电价(C语言)

今天是PTA题库解法讲解的第五天,今天我们要讲解A-B,题目如下: 解题思路: 要解决这个问题,我们可以编写一个C语言程序,首先判断输入的月用电量是否有效(即大于等于0)。如果有效,我们根据阶梯电价计算电费:对于50千瓦时及以下的部分,按0.53元/千瓦时计费;超过50千瓦时的部分,每千瓦时额外增加0.05元计费。然后输出最终的电费,保留两位小数。 #include <stdio.h> int main() { double electricity, cost; scanf("%lf", &electricity); if (electricity < 0) { printf("Invalid Value!\n"); } else if (electricity <= 50) { cost = electricity * 0.53; printf("cost = %.2f\n", cost); } else { cost = 50 * 0.53 + (electricity - 50) * (0.53 + 0.05); printf("cost = %.2f\n", cost); } return 0; } 这段代码首先读取月用电量,然后根据用电量计算电费并输出。如果输入的用电量小于0,则输出"Invalid Value!"。 提交结果: 本题通过,今天的讲解到此为止~

git常用操作

在服务器上创建一个新项目:git init --bare 项目名.git 如git init --bare example.git 项目创建后,不允许自行在example.git里面添加和修改任何文件。 必须先git clone example.git example后,再在example里面添加或修改文件,然后用git add、git commit和git push origin命令将代码提交到example.git中。 另外,每一位代码提交人都有一个用户名和邮箱地址,是写在example/.git/config文件里面的。 [user] name = 用户名 [user] email = 邮箱地址 从服务器上通过SSH下载一份已有项目的代码到本地电脑:git clone "ssh://用户名@域名/服务器上的项目路径.git" "要下载到本地电脑的哪个文件夹里面" 如git clone "ssh://oct1158@www.example.com/home/hahaha/xxxxx.git" my_folder 命令执行完成后本地电脑上就会出现my_folder文件夹,里面存放的是刚才下载的代码。 下载完成后需用“git checkout 分支名”命令切换到想要的分支上。 如果ssh需要密钥文件登录,则需要把密钥文件放到~/.ssh/id_rsa中,并且权限必须是400。git会去自动读取,不用加任何命令参数。 密钥文件不能是.ppk格式!!!只能是id_rsa格式。 cp ~/myfile ~/.ssh/id_rsa chmod 400 ~/.ssh/id_rsa 特别注意:git init和git clone只能二选一,不能两个都执行!!!! git init是在服务器上创建新项目,git clone是从服务器上下载已有项目的代码到本地。 从服务器上下载最近的代码改动:git pull origin 刚才的git clone是下载一份全新的代码,而git pull origin是只下载最近添加和改动的文件。 查看日志:git log 按回车键往下翻,按q键退出。 里面的每一次提交都有一个40位的编号,如7286d29254b7b1d335eead4c2a2e062917eefd5f。 查看未提交的修改(不包括新创建的且未执行git add命令的文件):git diff 回退到某次提交,恢复所有已修改的文件,但不删除新创建的且未执行git add命令的文件:git reset --hard XXX。

【JS面试题 - 打印结果】++[[]][+[]] + [+[]]

现有一段代码,说出打印结果 ++[[]][+[]] + [+[]] 这道题考验的是运算符的基础知识,下面来逐步分析: 先把表达式按照优先级最低的运算符(+)进行分割,得到两部分: ++[[]][+[]] 和 [+[]] ++[[]][+[]] 表达式中++运算符优先级最低,所以先对 [[]][+[]] 进行运算: 这个表达式的目的是:取数组 [[]] 的第 [+[]] 项。 [[]]:表示数组中有一个元素为[]。 [+[]]:+[]会将[]转为Number类型,由于[]是对象类型,所以转换后得到:0,结果为[0]。具体流程为:由于+运算符会将数据转为Number类型,首先查看[].valueOf是否为Number,结果是[],并不是Number。所以需要toString,[].toString()得到 “”。最终把字符""转为数字,即0。隐式转换详情可看另一篇文章:隐式类型转换详解。 所以[[]][+[]]结果为:[[]][0]也就是[]。 那么++[]的结果为1。 结果: 1。 [+[]] 通过上述流程可知,[+[]] 的结果为[0]。 最终运算 经过上述步骤,此时表达式已经转换为:1 + [0]。 由于+运算符右侧为非原始类型(复杂类型<对象>),所以需要尝试将其转为原始类型。 流程如下: [0].valueOf 得到 [0],所以继续转换。[0].toString 得到字符 “0”,此时数据已为原始类型,停止转换。至此,表达式变为:1 + “0”,所以答案为"10"。 结果 “10”

【JS】统计字符出现次数

现有一字符,要求统计每一个字符出现次数。 let str = "cbdbadcacbbdbacac" 遍历 let str = "cbaddacbc" let res = {} for (let i = 0; i < str.length; i++) { if (res[str[i]]) { res[str[i]]++ } else { res[str[i]] = 1 } } console.log(res); // {c: 3, b: 2, a: 2, d: 2} reduce const result = str.split("").reduce((acc, current) => { if (acc[current]) { acc[current]++ } else { acc[current] = 1 } return acc }, {}) console.

基于SSM框架的购物商城系统论文

摘 要 网络技术和计算机技术发展至今,已经拥有了深厚的理论基础,并在现实中进行了充分运用,尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代,所以对于信息的宣传和管理就很关键。因此商城购物信息的管理计算机化,系统化是必要的。设计开发购物商城系统不仅会节约人力和管理成本,还会安全保存庞大的数据量,对于商城购物信息的维护和检索也不需要花费很多时间,非常的便利。 购物商城系统是在MySQL中建立数据表保存信息,运用SSM框架和Java语言编写。并按照软件设计开发流程进行设计实现。系统具备友好性且功能完善。管理员登录进入本人后台之后,管理商品和用户,查看和回复用户对商品的评价,管理不同状态的订单。用户管理收货地址,管理不同状态的订单,收藏商品,评价商品。 购物商城系统在让商城购物信息规范化的同时,也能及时通过数据输入的有效性规则检测出错误数据,让数据的录入达到准确性的目的,进而提升购物商城系统提供的数据的可靠性,让系统数据的错误率降至最低。 关键词:购物商城系统;MySQL;SSM框架 Abstract Network technology and computer technology have developed so far, they already have a solid theoretical foundation and have been fully used in reality, especially the software based on computer operation has attracted the attention of all walks of life. In addition, now that people have entered the information age, the promotion and management of information is very important. Therefore, it is necessary to computerize and systemize the management of shopping information in shopping malls.

【软考---系统架构设计师】特殊的操作系统介绍

目录 一、嵌入式系统(EOS) (1)嵌入式系统的特点 (2)硬件抽象层 (3)嵌入式系统的开发设计 二、实时操作系统(RTOS) (1)实时性能指标 (2)调度算法 (3)常见实时操作系统 三、微内核操作系统 一、嵌入式系统(EOS) (1)嵌入式系统的特点 嵌入式系统主要由于嵌入式硬件平台,相关支撑硬件,嵌入式操作系统,支撑软件和应用软件组成。其中,嵌入型,专用性和计算机系统是嵌入式系统的三个核心要素。 特点: (1)系统专用性强 (2)系统实时性强 (3)软硬件依赖性强 (4)处理器专用 (5)多种技术紧密结合 (6)系统透明性 (7)系统资源受限 (2)硬件抽象层 嵌入式操作系统特点: (1)微型化 (2)代码质量高 (3)专业化 (4)实时性强 (5)可裁减,可配置 针对不同的硬件平台,操作系统通常建立在一个硬件抽象层上,该层次位于底层硬件和内核之间,为内核提供各种方便移植的宏定义接口,在不同的平台移植时,只需要修改宏定义即可。 与硬件相关,与操作系统相关。 (3)嵌入式系统的开发设计 嵌入式系统的开发设计师交叉开发环境 (1) 基于硬件的低功耗设计: 板级电路低功耗设计;选择低功耗处理器;总线的低功耗设计;接口驱动电路的设计;分区分时供电技术 (2)基于软件的低功耗设计: 编译优化技术;软件和硬件的协同设计(硬件功能交由软件完成);算法优化(低时间复杂度) 二、实时操作系统(RTOS) (1)实时性能指标 任务切换时间 中断处理相关的时间指标 中断延迟时间 中断响应时间 系统响应时间(对用户的输入或请求作出反应时间) 信号量混洗时间(从一个任务释放信号量等到另一个等待该信号量的任务被激活的时间延迟) (2)调度算法 这里我就列举一些常见的: (1)优先级调度算法:根据优先级高低进行排序,按时间顺序进行高优先级调度 (2)抢占式优先级调度算法:在优先级调度基础上,允许高优先级任务抢占低优先级任务 (3)时间轮转调度:调度程序会依次调度每个任务运行一个小的时间片,然后再调度另一个任务。每个任务运行完一个时间片,无论是否结束都会释放cpu让下一个任务进行(纯粹的时间轮转不满足实时系统的要求,取而代之的是基于优先级的抢占式时间轮转调度) (3)常见实时操作系统 常见的RTOS有:VxWorks,RT-Linux,ONX,pSOS 三、微内核操作系统 现代操作系统大多拥有两种工作状态,分别是核心态和用户态。一般应用程序工作在用户态,而内核模块和最基本的操作系统核心工作在核心态。 将传统的操作系统代码放置到最高层,从操作系统中去掉尽可能多的东西,而留下最小的核心,称之为微内核。 操作系统的内核服务:异常和中断,计时器,I/O管理

Stable Diffusion实现光影字效果

昨天下午有人在群里发光影图片,大家都觉得很酷,我没怎么在意。直到早上我在小红书看到有人发同款图片,只是一晚上的时间点赞就超过了8000,而且评论数也很高,也可以做文字定制变现。研究了一下发现这个效果不难实现,在这里跟大家一起分享。 这是小红书的爆款笔记 下面是我做的 SD参数 这个效果不难实现,使用Stable Diffusion + Controlnet垫图就可以。 大模型我使用的是majicmixRealistic_v6.safetensors,这里的大模型并不关键,使用二次元风格的模型也可以实现不同风格的光影效果,大家可以自由尝试。 正向提示词 masterpiece,best quality,highres,street,light,at night 提示词也可以自己进行修改,比如可以换成美女,河流等等,如果画人物反向提示词可能需要多写一些。 迭代步数我调整为25,过多迭代步数可能会导致文字不清晰,多测试几次找到自己最满意的效果。 制作文字图 因为采用的是垫图实现,所以这里要先创建一下文字底稿,可以使用稿定设计,或者Photoshop等拿手工具。 Controlnet垫图 这是最关键的一步啦,我们把上面的文字图放到Controlnet上面,预处理器不用选择,模型选择control_v1p_sd15_brightness.safetensors或者lightingBasedPicture_v10.safetensors,这两个模型各有千秋。 最后修改控制权重在0.5左右,引导终止时机在0.6左右,开始抽卡! 模型网站在这里: huggingface.co/ioclab/cont… civitai.com/models/8053… 不方便下载的同学可以进网盘下载: pan.quark.cn/s/436b4dcff… 小tip: 这里有的小伙伴控制台可能会出现Error:找不到对应的yaml文件 这里系统会自动去寻找cldm_v15.yaml,所以在使用上也没有问题,但是如果有小伙伴像我一样强迫症,可以把此文件复制一份,重命名为上面对应的模型文件,比如control_v1p_sd15_brightness.yaml 这里是我用xyz脚本测试的Controlnet权重和引导终止时机对图片的影响,给大家参考 写在最后 感兴趣的小伙伴,赠送全套AIGC学习资料,包含AI绘画、AI人工智能等前沿科技教程和软件工具,具体看这里。 ​ AIGC技术的未来发展前景广阔,随着人工智能技术的不断发展,AIGC技术也将不断提高。未来,AIGC技术将在游戏和计算领域得到更广泛的应用,使游戏和计算系统具有更高效、更智能、更灵活的特性。同时,AIGC技术也将与人工智能技术紧密结合,在更多的领域得到广泛应用,对程序员来说影响至关重要。未来,AIGC技术将继续得到提高,同时也将与人工智能技术紧密结合,在更多的领域得到广泛应用。 一、AIGC所有方向的学习路线 AIGC所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。 二、AIGC必备工具 工具都帮大家整理好了,安装就可直接上手! 三、最新AIGC学习笔记 当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。 四、AIGC视频教程合集 观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。 五、实战案例 纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。 ​

ES6—Module 的语法

export命令 ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。 模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。 一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。下面是一个 JS 文件,里面使用export命令输出变量。 //profile.js //分别暴露 /* export let firstName = "li"; export let lastName = "siyu"; export function birthdy() { console.log("hello world"); } */ //统一暴露(优先使用) let firstName = "li"; let lastName = "siyu"; function birthdy() { console.log("hello world"); } export { firstName, lastName, birthdy }; 通常情况下,export输出的变量就是本来的名字,但是可以使用as关键字重命名。 function v1(a, b) { return a * b; } function v2(a, b) { return a - b; } export { v1 as streamV1, v2 as streamV2, v2 as streamVersion }; 重命名后,v2可以用不同的名字输出两次。

Springboot+vue的高校实习管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频: Springboot+vue的高校实习管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构,通过Spring + SpringBoot + Mybatis +Vue+Maven来实现。MySQL数据库作为系统数据储存平台,实现了基于B/S结构的Web系统。界面简洁,操作简单。 报告截图:

【WEEK4】 【DAY3】Integrating SSM Framework: Modify and Delete Data 【English Version】

2024.3.20 Wednesday Following the previous article 【WEEK4】 【DAY2】Integrating SSM Framework: Overview and Adding Data 【English Version】 Contents 7.6. Modify Functionality7.6.1. Modify BookController.java7.6.2. Modify allBook.jsp7.6.3. Create New updateBook.jsp7.6.4. Modify MyBatis-config.xml7.6.5. Running the Application 7.7. Deletion Function7.7.1. Modify BookController.java7.7.2. Modify allBook.jsp7.7.3. Modify BookDao.xml7.7.4. Execution 7.6. Modify Functionality 7.6.1. Modify BookController.java (The complete BookController.java code with delete functionality is located in 7.7.1.) // Jump to the modify page @RequestMapping("/toUpdate") public String toUpdatePaper(int id,Model model){ Books books = bookService.

leetcode排列硬币

求根公式解法 public static int arrangeCoins(int n) { return (int) ((Math.sqrt((long) n * 8 + 1) - 1) / 2); } 二分法 边界问题依然不懂 public int arrangeCoins(int n) { int l = 1,r = n; while(l < r) { int m = (r - l + 1) / 2 + l; if((long)m * (m + 1) <= (long)2 * n) { l = m; } else { r = m - 1; } } return l; } public int arrangeCoins(int n) { int l = 0,r = n; while(l <= r) { int m = (r - l) / 2 + l; if((long)m * (m + 1) < (long)2 * n) { l = m + 1; } else if((long)m * (m + 1) > (long)2 * n){ r = m - 1; } else { return m; } } return r; } 牛顿迭代 //大值会溢出 public int arrangeCoins(int n) { if(n == 0) return -1; return (int)sqrt(n, n); } //y ^ 2 = x -> y = (y + x/y)/2 //r = (x+(2n-x)/x)/2 //2r = x + 2n/x -1 //2r * x = x ^ 2 + 2n -x //2r = 2n + x * x - x //2n - x * x - x = 0 //2n + x * x - x = 2 * x * x //2n + x * x - x = 2 * r //(2n + x * x - x)/2 = r //n + x * x/2 -x/2 = r public double sqrt(int n, double x) { double r = (x+(2*n+x)/x)/2; if(r == x) { return r; } else { return sqrt(n, r); } } public int arrangeCoins(int n) { long m = n * 2L, x = n; while (x * (x + 1) > m) { //x = (x * x + m) / (2 * x + 1) //x * x + m = 2 * x * x + x //m = x * x + x x = (x * x + m) / (2 * x + 1); } return (int) x; }

JVM内存溢出排查

JVM内存溢出排查主要涉及到定位问题发生的原因以及确定哪些对象占用了过多的内存。以下是一些排查内存溢出的基本步骤: 查看异常信息: 当JVM发生内存溢出时,会抛出OutOfMemoryError异常,并伴随异常信息。这些信息可以帮助初步定位问题,比如是堆内存溢出还是方法区内存溢出。 使用工具获取堆转储(Heap Dump): 当堆内存溢出时,可以使用如jmap工具来获取堆转储文件(Heap Dump)。这个文件包含了某一时刻堆中对象的情况,是排查内存溢出的重要依据。 分析堆转储文件: 使用MAT(Memory Analyzer Tool)或VisualVM等工具来分析堆转储文件。这些工具可以帮助识别哪些对象占用了过多的内存,以及这些对象是如何被引用的。 代码审查: 根据工具分析的结果,审查相关代码。检查是否存在大对象的分配,如大数组或大量创建的对象。同时,注意检查集合类中是否有无用对象的引用,以及是否存在死循环、递归或循环次数过多等问题。 调整JVM参数: 如果堆内存确实不足,可以考虑调整JVM的启动参数,如增加-Xmx参数的值以增大堆内存的最大值。 检查方法区内存溢出: 如果是方法区内存溢出,可能是因为使用了过多的静态变量、常量池被大量占用,或者第三方框架(如Hibernate、Spring)产生了大量的动态类。这种情况下,需要优化代码,减少静态变量的使用,以及避免产生不必要的动态类。 检查是否存在内存泄露: 内存泄露是导致内存溢出的常见原因。通过工具分析堆转储文件,可以检查是否存在无用的对象被长时间持有引用,导致无法被GC回收。 考虑Finalizable对象: 检查是否有大量的自定义的Finalizable对象,或者框架内部提供的Finalizable对象。这些对象在垃圾回收时可能需要额外的处理,如果数量过多,可能会影响到垃圾回收的效率。 查看GC日志: 通过查看GC日志,可以了解垃圾回收的情况,包括回收的频率、回收的对象数量等。这有助于判断是否存在垃圾回收不及时或回收效率不高的问题。 在排查过程中,可能需要根据实际情况进行多次迭代和调整。同时,保持对代码和JVM运行原理的深入理解,有助于更准确地定位和解决内存溢出问题。

数据结构:图的最短路径

目录 一、最短路径的基本概念 二、无权图单源最短路径 三、Dijkstra算法(正权图单源) 3.1、算法的基本步骤 3.2、算法的实现 3.3、习题思考 3.3.1、网络延迟时间 四、A*算法(正权图单源单目标点) 4.1、算法的基本概念 4.2、算法的重要证明 五、Floyd算法(带权每对顶点间的最短路) 5.1、算法的基本原理 5.2、算法的实现 5.3、扩展 六、Bellman-Ford算法(负权图单源最短路径问题) 6.1、算法的基本原理 6.2、算法的实现 七、SPFA(贝尔曼福特队列优化) 7.1、算法的基本思想 7.2、算法的实现 本篇所有证明都是博主自己想的,如有疑问,扔给GPT,他会帮你解答。 一、最短路径的基本概念 无权图:路径包含的边的条数。带权图:路径包含的各边权值之和。长度最小的路径称为最短路径,最短路径的长度也称为最短距离。 二、无权图单源最短路径 无权图单源最短路径使用BFS求出,时间复杂度为O(n+e)。该算法可以求出单源到所有顶点的最短路,并且可以通过静态链表的方式存储各顶点的最短路径信息。 在BFS访问的过程中,当访问某个顶点时,就确定了该点与源点的最短距离。 #include<bits/stdc++.h> using namespace std; #define n 10 struct Edge{ int VerName; Edge * next; }; struct Vertex{ int VerName; Edge * edge=nullptr; }; vector<int> path(n); Vertex Head[n]; vector<int> dist(n,0x3f3f3f3f); void BFS(Vertex * Head,int s){ dist[s]=0;path[s]=-1; queue<int> q; q.push(s); while(!q.empty()) { int pre=q.front();q.pop(); for(Edge * edge=Head[pre].

RabbitMQ部署指南

RabbitMQ部署指南 RabbitMQ部署指南1.单机部署1.1.下载镜像1.2.安装MQ 2.安装DelayExchange插件2.1.下载插件2.2.上传插件2.3.安装插件 3.集群部署2.1.集群分类2.2.获取cookie2.3.准备集群配置2.4.启动集群2.5.测试 4.镜像模式4.1.镜像模式的特征4.2.镜像模式的配置4.3.测试 5.仲裁队列5.1.添加仲裁队列5.2.测试5.3.集群扩容 RabbitMQ部署指南 1.单机部署 我们在Centos7虚拟机中使用Docker来安装。 1.1.下载镜像 方式一:在线拉取 docker pull rabbitmq:3.8-management 方式二:从本地加载 上传到虚拟机中后,使用命令加载镜像即可: docker load -i mq.tar 1.2.安装MQ 执行下面的命令来运行MQ容器: docker run \ -e RABBITMQ_DEFAULT_USER=root \ -e RABBITMQ_DEFAULT_PASS=123456 \ -v mq-plugins:/plugins \ --name mq \ --hostname mq1 \ -p 15672:15672 \ -p 5672:5672 \ -d \ rabbitmq:3.8-management 2.安装DelayExchange插件 官方的安装指南地址为:https://blog.rabbitmq.com/posts/2015/04/scheduling-messages-with-rabbitmq 上述文档是基于linux原生安装RabbitMQ,然后安装插件。 因为我们之前是基于Docker安装RabbitMQ,所以下面我们会讲解基于Docker来安装RabbitMQ插件。 2.1.下载插件 RabbitMQ有一个官方的插件社区,地址为:https://www.rabbitmq.com/community-plugins.html 其中包含各种各样的插件,包括我们要使用的DelayExchange插件: 可以去对应的GitHub页面下载3.8.9版本的插件,地址为https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/tag/3.8.9这个对应RabbitMQ的3.8.5以上版本。 2.2.上传插件 因为我们是基于Docker安装,所以需要先查看RabbitMQ的插件目录对应的数据卷。如果不是基于Docker,请重新创建Docker容器。 我们之前设定的RabbitMQ的数据卷名称为mq-plugins,所以我们使用下面命令查看数据卷: docker volume inspect mq-plugins 可以得到下面结果: 接下来,将插件上传到这个目录即可: 2.3.安装插件 最后就是安装了,需要进入MQ容器内部来执行安装。我的容器名为mq,所以执行下面命令: docker exec -it mq bash 执行时,请将其中的 -it 后面的mq替换为你自己的容器名.

数据结构万字总结(超级详细)第二章——线性表

线性表 定义 线性表是具有相同数据类型的n(n≥0)个数据元素的有限 序列 特点 除第一个元素外,每个元素有且仅有一个直接前驱;除最后一个元素外,每个元素有且仅 有一个直接后继 操作 初始化、增、删、查、改、销毁 元素的下标与位序 下标从0开始,位序从1开始 分类(根据存储结构来划分的) 顺序表 顺序存储 定义 用顺序存储的方式实现线性表。顺序存储:把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中 实现 静态分配(数组实现) 扩展容量不方便,缺乏灵活性、但是内存管理简单,不存在内存泄漏的问题(内存泄漏——只申请内存不释放内存) 动态分配(malloc) 空间利用灵活,但是内存管理复杂 特点 优点 随机访问,即可以在 O(1) 时间内找到第 i 个元素 存储密度高 缺点 扩展容量不方便,即便采用动态分配的方式实现,拓展长度的时间复杂度也比较高 插入、删除操作不方便,需要移动大量的元素 顺序存储、随机存取 操作 插入:移动元素(n/2)次 删除:移动元素(n-1)/ 2次 查找:比较次数:(n+1)/ 2 查找最多,即(n+1),记住,删除肯定是要小的,即(n-1),而插入是增多,即n 链表 链式存储 单链表 定义 用链式存储实现的线性表,链式存储:逻辑上相邻但是物理存储结构上不相邻,每个结点除了存放数据元素外,还要存储指向下一个节点的指针 实现 带头结点有什么好处? 带头结点 写代码更方便 不带头结点 写代码更麻烦,对第一个结点的处理需要使用不同的代码逻辑。比如判空操作 特点 优点 扩展容量方便 插入、删除操作很方便、不需要移动大量的元素 缺点: 只能顺序访问 存储密度低 随机存储、顺序存取 操作:插入、删除、查找。三种操作的复杂度都为O(n) 建立 尾插法 头插法:可用于实现单链表逆置 双链表,如下: 定义 由于单链表不能逆向检索,因此出现了双向链表。 实现 特点 存储密度更低,不具备随机存取特性

P1090 [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G

例题 思路:动态的获取队列中最小的两个 然后加在一起呗——要不每次都搬多的得累死 优先队列! STL里的优先队列 : priority_queue 长什么样呢? priority_queue<int>q; //从小到大 小根堆 priority_queue<int,vector<int>,greater<int> >q; //从大到小 大根堆 priority_queue<int,vector<int>,less<int> >q; #include<bits/stdc++.h> #define int long long #define endl '\n' #define INF 0x3f3f3f3f using namespace std; const int N = 100010; int n, x,num,ans; signed main(){ std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); priority_queue<int, vector<int>,greater<int>> pq; cin>>n; while(n--){ cin>>num; pq.push(num); } while(pq.size()>1){ int a = pq.top(); pq.pop(); int b = pq.top(); pq.pop(); pq.push(a+b); ans =ans+ a+b; } cout<<ans; }

[ABC298D] Writing a Numeral

例题 #include <bits/stdc++.h> #define endl '\n' #define int long long #define INF 0x3f3f3f3f3f const int N = 1000010; const int mod = 998244353; using namespace std; int arr[N]; //1 ≤ Q ≤ 6e10 //当然是要用快速幂 int qmi(int a,int b,int mod){ a %= mod; int res = 1; while(b>0){ if(b&1) res = res*a%mod; a = a*a%mod; b >>= 1; } return res; } signed main() { int n; cin>>n; queue<int> s; //插入队头 1 s.

数据结构:堆和二叉树遍历

堆的特征 1.堆是一个完全二叉树 2.堆分为大堆和小堆。大堆:左右节点都小于根节点 小堆:左右节点都大于根节点 堆的应用:堆排序,topk问题 堆排序 堆排序的思路: 1.升序排序,建小堆。堆顶就是这个堆最小的数,堆顶和这个堆的最后一个数换位置,然后再把最后一个数取出,再pop这个数。就得到最小值。像这样每次取一个最小值,再删掉。依次把取出的数放在数组中,就得到升序排序了。 2.降序排序,建大堆。思路同升序一样。 上面说的是向下调整。向下调整就是每次取个数,由于和堆的最后一个数交换了位置,取出之后的二叉树需要调整一下才能成为一个堆。如果是大堆,就比较堆顶的和左右子树,大于它,堆顶和大的那个交换,这样层层交换下去。 如果一共有k层,最坏交换k次,如果是N个节点,就是log(N+1)次。 堆排序就是排N个数嘛,时间复杂度就是O(N*logN),空间复杂度就是O(N)。 向上调整: 向上调整可以应用于尾部插入数。调成一个大堆后停止。 对于一个随机数组,建大堆,向下调整法: 对于一个随机数组建小堆,向上调整法: topk问题 如何从10000个数中取出最大的50个数?此问题也可以用于:内存空间不够,建堆数量有限,如何在大量的数据中取出前k个最大(小)的数。 答:先取出这些数据中前50(k)个建小堆,剩下的数和堆顶相比,遇到大于堆顶的数就直接替换掉堆顶的数。替换一次,小堆也要向下调整一次,保持它是一个小堆。这样比到最后一个数。就能保持这个小堆是这10000个数中最大的50个了。 如果是取出最小的50个数,那就是建大堆了。遇到比堆顶小的就替换、调整等。 二叉树的遍历 用链表建二叉树。 typedef struct BinaryNode { int val; struct BinaryNode* left; struct BinaryNode* right; }BTNode,*pBTNode; 如上述代码所示,树的一个节点存储三个值,一个是它的数据,一个是它指向的左子树指针,一个是指向右子树的指针。如果左子树和右子树都是空,就指向空。 这样由链表构建的一个二叉树。可以通过三种遍历方式来读取整个二叉树的数据。 前序:根----左子树----右子树 中序:左子树----根----右子树 后序:左子树----右子树----根 前中后序的命名是根据访问根的顺序来命名的。以前序遍历来举例:

【JS】如何避免输入中文拼音时触发input事件

现有一段代码,监听input事件。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <input type="text"> <script> let ipt = document.querySelector("input") function search() { console.log("搜索内容:", ipt.value); } ipt.addEventListener('input', function () { console.log('input事件触发'); search() }) </script> </body> </html> 通过控制台可以看到:当输入英文字符时,监听器正常工作。 但如果输入中文拼音时,通过控制台可以发现,在未确认中文前,每次输入拼音都触发了input事件,在某些场景下会白白浪费性能。 可以通过监听compositionstart和compositionend两个 「合成事件」,准确获取中文输入结束的时机。 ipt.addEventListener('compositionstart', function () { console.log('start'); }) ipt.addEventListener('compositionend', function () { console.log('end'); }) 合成事件表示多个字符合成一个单词,比如中文拼音,可以发现英文单词由于不需要合成,所以并不会触发合成事件。 此时可以在全局定义一个变量,表示是否合成完毕,只有合成完毕后,再进行input事件的回调函数。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="

Apache James数据库存储用户信息的密码加密问题

项目场景 Apache James邮件服务器使用数据库来存储用户信息的密码加密问题: 将James的用户改为数据库存储James密码是如何加密验证的 1.将James的用户改为数据库存储 1、修改存储方式 找到james-2.3.2\apps\james\SAR-INF\config.xml 找到<users-store>标签,注释掉原来文件存储的方式,改为数据库的方式 maildb:是后面配置的数据源名称 mail_users:是存储用户信息的表名 <users-store> <!-- 注释掉原来文件存储的方式 --> <!-- <repository name="LocalUsers" class="org.apache.james.userrepository.UsersFileRepository"> <destination URL="file://var/users/"/> </repository> --> <!-- 改为数据库的方式 --> <repository name="LocalUsers" class="org.apache.james.userrepository.JamesUsersJdbcRepository" destinationURL="db://maildb/mail_users"> <sqlFile>file://conf/sqlResources.xml</sqlFile> </repository> </users-store> 2.、配置数据库信息 找到<data-source>标签,根据具体数据库类型进行配置,下面已国产达梦数据库为例 maildb:数据源名称 <data-source name="maildb" class="org.apache.james.util.dbcp.JdbcDataSource"> <driver>dm.jdbc.driver.DmDriver</driver> <dburl>jdbc:dm://127.0.0.1:5236/test_mail</dburl> <user>test</user> <password>test123</password> <max>50</max> </data-source> 3、添加依赖包 因为我用的是达梦数据库,james里面没有这个数据库的依赖包,所以需要额外添加,如果是mysql、oracle常用的数据库就不需要再额外添加,因为james已经支持。 找到james-2.3.2\lib,然后把需要的依赖包放进去 4、创建用户表 正常情况下会自动创建,sql语句在james-2.3.2\apps\james\conf\sqlResources.xml 如果不会自动创建,那么自己把sql语句复制出来执行 CREATE TABLE "MAIL_USERS" ( "USERNAME" VARCHAR2(64) NOT NULL, "PWDHASH" VARCHAR2(50), "PWDALGORITHM" VARCHAR2(20), "USEFORWARDING" NUMBER(1,0), "FORWARDDESTINATION" VARCHAR2(255), "USEALIAS" NUMBER(1,0), "ALIAS" VARCHAR2(255), PRIMARY KEY("