当前位置: 首页 > news >正文

C++-----动态规划

目录

一、动态规划的基本思想

 二、设计动态规划法的步骤

三、动态规划问题的特征

4.1 矩阵连乘积问题

 4.1.1 分析最优解的结构

4.1.2 建立递归关系

4.1.3 计算最优值

 4.1.3 计算最优值

 4.1.3 构造最优解

 4.2 动态规划算法的基本要素

4.2.1 最优子结构

4.2.2 重叠子问题

 算法4.3  计算矩阵连乘积的递归算法

4.1.3 备忘录方法

算法4.4计算矩阵连乘积的备忘录算法

 ​编辑

 4.3 最长公共子序列

 4.3.2 子问题的递归结构

 4.3.3 计算最优值

 4.4 最大子段和


一、动态规划的基本思想

  • 动态规划算法通常用于求解具有某种最优性质的问题。
  • 在这类问题中,可能会有许多可行解。
l 每一个解都对应于一个值,我们希望找到具有最优值的解。
  • 基本思想是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
l 适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。
  • 如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。
l 我们 可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。
  • 就是动态规划法的基本思路。
l 具体的动态规划算法多种多样,但它们具有相同的填表格式。

 二、设计动态规划法的步骤

1. 找出最优解的性质,并刻画其结构特征;
2. 递归地定义最优值(写出动态规划方程);
3. 以自底向上的方式计算出最优值;
4. 根据计算最优值时得到的信息,构造一个最优解。
l 步骤 1 3 是动态规划算法的基本步骤。
l 只需要求出最优值的情形,步骤 4 可以省略;
l 需要求出问题的一个最优解,则必须执行步骤 4。

三、动态规划问题的特征

  • 动态规划算法的有效性依赖于问题本身所具有的两个重要性质:
1. 优子结构:
  • 当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质。
2. 重叠 子问题:
  • 在用递归算法自顶向下解问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只解一次,而后将其解保存在一个表格中,在以后尽可能多地利用这些子问题的解。

4.1 矩阵连乘积问题

  • m×n矩阵An×p矩阵B相乘需耗费 的时间
  • 我们mnp作为两个矩阵相乘所需时间的测量值
  • 现在假定要计算三个矩阵ABC的乘积,有两种方式计算此乘积
1. A 乘以 B 得到矩阵 D ,然后 D 乘以 C 得到最终结果,这种乘法的 顺序为 AB C
2. 乘法的顺序为 A BC
  • 尽管这两种不同的计算顺序所得的结果相同,但时间消耗会有很大的差距。

 

 

  • 定义:给定n个矩阵{A1,A2,…,An},其中AiAi+1是可乘的,i=1,2,…n-1。考察这n个矩阵的连乘积A1A2…An。
  • 由于矩阵乘法满足结合律,所以计算矩阵的连乘可以有许多不同的计算次序。
  • 这种计算次序可以用加括号的方式来确定。
  • 若一个矩阵连乘积的计算次序完全确定,也就是说该连乘积已完全加括号,则可以依此次序反复调用2个矩阵相乘的标准算法计算出矩阵连乘积

  • 完全加括号的矩阵连乘积可递归地定义为:
1. 单个矩阵是完全加括号的;
2. 矩阵连乘积 A 是完全加括号的,则 A 可表示为 2 个完全加括号的矩阵连乘积 B C 的乘积并加括号,即A=(BC)   
  • 设有四个矩阵A, B, C, D,总共有五种完全加括号的方式:

(A((BC)D))

(A(B(CD)))

((AB)(CD))

(((AB)C)D)

((A(BC)D))

  • 设有四个矩阵A, B, C, D,它们的维数分别是:

  A=50×10,  B=10×40,  C=40×30,  D=30×5

  • 矩阵AB可乘的条件: 矩阵A的列数等于矩阵B的行数。
  • Ap×q的矩阵, Bq×r的矩阵, 乘积是p×r的矩阵;
计算量是 pqr。
  • 上述5种完全加括号方式的计算工作量为:

(A((BC)D)), (A(B(CD))), ((AB)(CD)), (((AB)C)D), ((A(BC)D))

      16000,    10500,   36000,       87500,         34500

BC: 10×40×30 = 12000,

(BC)D: 10×30×5 = 1500,

(A((BC)D)): 50×10×5 = 2500

 

  • 给定n个矩阵{A1,A2,…,An},其中AiAi+1是可乘的,i=12…n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少?
  • 穷举法:列举出所有可能的计算次序,并计算出每一种计算次序相应需要的数乘次数,从中找出一种数乘次数最少的计算次序。

 

 4.1.1 分析最优解的结构

  • 将矩阵连乘积AiAi+1Aj 简记为A[i:j], 这里ij;
  • 考察计算A[1:n]的最优计算次序。
  • 设这个计算次序在矩阵AkAk+1之间将矩阵链断开,1k<n,则其相应完全加括号方式为(A1A2…Ak)(Ak+1Ak+2…An)
  • 计算量:A[1:k]的计算量加上A[k+1:n]的计算量,
  • 再加上A[1:k]A[k+1:n]相乘的计算量
  • 特征:计算A[1:n]的最优次序所包含的计算矩阵子链 A[1:k]A[k+1:n]的次序也是最优的。
  • 矩阵连乘计算次序问题的最优解包含着其子问题的最优解。
  • 这种性质称为最优子结构性质
  • 问题的最优子结构性质是该问题可用动态规划算法求解的显著特征。

4.1.2 建立递归关系

 

 

4.1.3 计算最优值

  • 对于1ijn不同的有序对(i, j)对应于不同的子问题。因此,不同子问题的个数最多只有
  • 在递归计算时,许多子问题被重复计算多次。
  • 这也是该问题可用动态规划算法求解的又一显著特征。
  • 用动态规划算法解此问题,可依据其递归式以自底向上的方式进行计算。
  • 在计算过程中,保存已解决的子问题答案。
  • 每个子问题只计算一次,在后面需要时只要简单查一下,从而避免大量的重复计算,最终得到多项式时间的算法。

 

#define NUM 51
int p[NUM];
int m[NUM][NUM];
int s[NUM][NUM];
void MatrixChain (int n)
{for (int i=1;  i<=n;  i++) m[i][i] = 0;for (int r=2;  r<=n;  r++)for (int i=1;  i<=n-r+1;  i++) {int j=i+r-1; //计算初值,从i处断开m[i][j] = m[i+1][j]+p[i-1]*p[i]*p[j];s[i][j] = i; for (int k=i+1;  k<j;  k++) { int t = m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];if (t < m[i][j]) {m[i][j] = t; s[i][j] = k;}}}
}

 

 4.1.3 计算最优值

                                                                                                    计算顺序

 

 

 

 

  • 依据其递归式以自底向上的方式进行计算。
  • 在计算过程中 , 保存已解决的子问题答案。
  • 每个子问题只计算一次 , 而在后面需要时只要简单查一下 ,从而避免大量的重复计算, 最终得到多项式时间的算法。

 

         计算顺序

 4.1.3 构造最优解

  • s[i][j]已经存储了构造最优解所需要的足够的信息。
  • 每个部分的最优加括号方式可以根据数组s的相应元素得出。
  • 照此递推下去,最终可以确定A[1:n]的最优完全加括号方式,即构造出问题的一个最优解。
//算法4.2计算矩阵连乘积最优解的递归算法
void TraceBack(int i, int j) 
{ if(i==j) printf("A%d", i);else {printf("(");TraceBack(i,s[i][j]); TraceBack(s[i][j]+1,j); printf(")"); }
}

 

 4.2 动态规划算法的基本要素

4.2.1 最优子结构

  • 设计动态规划算法的第一步是刻画最优解的结构。
  • 当问题的最优解包含其子问题的最优解时,称该问题具有最优子结构性质。
  • 问题的最优解子结构性质提供了该问题可用动态规划求解的重要线索。
  • 动态规划算法中,利用问题的最优子结构性质,以自底向上的方法递归的从子问题的最优解逐步构造出整个问题的最优解
  • 使我们能在相对小的子问题空间中考虑问题。

4.2.2 重叠子问题

  • 递归算法求解问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。
  • 这种性质称为子问题的重叠性质。
  • 动态规划算法,对每一个子问题只解一次,而后将其解保存在一个表格中,当再次需要解此子问题时,只是简单地用常数时间查看一下结果。

  • 通常不同的子问题个数随问题的大小呈多项式增长。
  • 用动态规划算法只需要多项式时间,从而获得较高的解题效率。

 

 算法4.3  计算矩阵连乘积的递归算法

//算法4.3  计算矩阵连乘积的递归算法int Recurve(int i, int j)
{if (i == j) return 0;int u = Recurve(i, i)+Recurve(i+1,j)+p[i-1]*p[i]*p[j];s[i][j] = i;for (int k = i+1; k<j; k++) {int t = Recurve(i, k) + Recurve(k+1,j)+p[i-1]*p[k]*p[j];if (t<u) { u = t; s[i][j] = k;}}m[i][j] = u;return u;
} 

 

 

 

 

4.1.3 备忘录方法

  • 备忘录方法是动态规划算法的变形。
  • 与动态规划算法一样,备忘录方法用一个表格保存已解决的子问题的答案,再碰到该子问题时,只要简单地查看该子问题的解答,而不必重新求解。
  • 备忘录方法的控制结构与直接递归方法的控制结构相同,区别仅在于备忘录方法为每个解过的子问题建立了备忘录以备需要时查看,避免了相同子问题的重复求解。

算法4.4计算矩阵连乘积的备忘录算法

int LookupChai  (int i, int j)
{if (m[i][j]>0) return m[i][j];if (i==j) return 0;int u = LookupChain(i,i)+LookupChain(i+1,j)+p[i-1]*p[i]*p[j];s[i][j] = i;for (int k = i+1; k<j; k++) {int t = LookupChain(i,k)+LookupChain(k+1,j)+p[i-1]*p[k]*p[j];if (t < u) { u = t; s[i][j] = k;}}m[i][j] = u;return u;
}

 

 4.3 最长公共子序列

  • 若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,zk},是X子序列是指存在一个严格递增下标序列{i1,i2,…,ik}使得对于所有j=1,2,…,k有:zj=xij
  • 例如,序列Z={BCDB}是序列X={ABCBDAB}的子序列,相应的递增下标序列为{2357}
  • 给定2个序列XY,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列XY公共子序列
  • 给定2个序列X={x1,x2,…,xm}Y={y1,y2,…,yn},找出XY的最长公共子序列。

  • 设序列X={x1,x2,…,xm}Y={y1,y2,…,yn}的最长公共子序列为Z={z1,z2,…,zk} ,则
  1. xm=yn,则zk=xm=yn,且zk-1xm-1yn-1的最长公共子序列。
  2. xm≠ynzk≠xm,则Zxm-1Y的最长公共子序列。
  3. xm≠ynzk≠yn,则ZXyn-1的最长公共子序列。

 

 4.3.2 子问题的递归结构

  • 由最长公共子序列问题的最优子结构性质可知,要找出XY的最长公共子序列,可按以下方式递归地进行:
  1. xmyn时,找出Xm1Yn1最长公共子序列,然后在其尾部加上xm(=yn)即可得XY的一个最长公共子序列。
  2. xmyn时,必须解两个子问题,即找出Xm1Y的一个最长公共子序列及XYn1一个最长公共子序列。这两个公共子序列中较长者为XY的一个最长公共子序列。

  • c[i][j]记录序列和的最长公共子序列的长度。
  • Xi={x1,x2,…,xi}Yj={y1,y2,…,yj}
  • i=0j=0时,空序列是XiYj的最长公共子序列。
  • 故此时C[i][j]=0
  • 其它情况下,由最优子结构性质可建立递归关系如下:

 4.3.3 计算最优值

//算法4.5计算最长公共子序列的动态规划算法
#define NUM 100
int c[NUM][NUM];
int b[NUM][NUM];
void LCSLength (int m, int n, const char x[],char y[])
{  int i,j;//数组c的第0行、第0列置0for (i = 1; i <= m; i++) c[i][0] = 0;for (i = 1; i <= n; i++) c[0][i] = 0;//根据递推公式构造数组cfor (i = 1; i <= m; i++)for (j = 1; j <= n; j++){if (x[i]==y[j]) {c[i][j]=c[i-1][j-1]+1; b[i][j]=1; }		//↖else if (c[i-1][j]>=c[i][j-1]) {c[i][j]=c[i-1][j]; b[i][j]=2; }		//↑else { c[i][j]=c[i][j-1]; b[i][j]=3; }			//←}
}

 

 

 

 4.4 最大子段和

  • 给定由n个整数(包含负整数)组成的序列a1,a2,...,an,求该序列子段和的最大值。
  • 当所有整数均为负值时定义其最大子段和为0
  • 所求的最优值为:

  • 例如,当(a1,a2, ……a7,a8)=(1,-3, 7,8,-4,12, -10,6)时,最大子段和为:

                                   

  •  bj1j位置的最大子段和:

 

 

 

相关文章:

C++-----动态规划

目录 一、动态规划的基本思想 二、设计动态规划法的步骤 三、动态规划问题的特征 4.1 矩阵连乘积问题 4.1.1 分析最优解的结构 4.1.2 建立递归关系 4.1.3 计算最优值 4.1.3 计算最优值 4.1.3 构造最优解 4.2 动态规划算法的基本要素 4.2.1 最优子结构 4.2.2 重叠子问题 …...

2.2 Linux控制台访问CLI

系列文章目录 第1章 Linux Shell简介 第2章 Shell基础 <本章所在位置> 第3章 Bash Shell基础命令 第4章 Bash Shell命令进阶 第5章 Linux Shell深度理解 第6章 Linux环境变量 第7章 Linux文件权限 第8章 Linux文件系统的管理 第9章 Linux软件安装 第10章 Linux文本编辑器…...

代码随想录补打卡 509 斐波那契数列

代码如下 //斐波那契数列的第0项是0 第一项是1 func fib(n int) int { if n < 1 { return n } dp : make([]int,n1) dp[0] 0 dp[1] 1 for i : 2 ; i < n ; i { dp[i] dp[i-1] dp[i-2] } return dp[n] } 70 爬楼梯 代码如下 func climbStairs(n int) int …...

【每日一题Day195】LC1003检查替换后的词是否有效 | 栈

检查替换后的词是否有效【LC1003】 给你一个字符串 s &#xff0c;请你判断它是否 有效 。 字符串 s 有效 需要满足&#xff1a;假设开始有一个空字符串 t "" &#xff0c;你可以执行 任意次 下述操作将 t 转换为 s &#xff1a; 将字符串 "abc" 插入到 t…...

简单理解什么是序列化

为什么要序列化 序列化的目的就是为了对象可以在网络层进行传输&#xff0c; 比如通过后端传给前端数据。 什么是序列化 我们以Java为例。 序列化就是把对象转化为可传输的字节序列过程&#xff0c;这个字节序列可以是字符串&#xff0c;比如JSON格式的字符串&#xff0c;把…...

Django初识

1、简介 Django&#xff0c;是用python语言写的开源web开发框架&#xff0c;并遵循MVC设计。劳伦斯出版集团为了开发以新闻内容为主的网站&#xff0c;而开发出来了这个框架&#xff0c;于2005年7月在BSD许可证下发布。这个名称来源于比利时的爵士音乐家DjangoReinhardt&#…...

ARM嵌入式编译器-volatile关键字对编译器优化的影响

volatile限定符告知计算机&#xff0c;其他agent&#xff08;而不是变量所在的程序&#xff09;可以改变该变量的值。通常它被用于硬件地址以及在其他程序或同时运行的线程中共享数据。要求编译器不要对其描述的对象作优化处理&#xff0c;对它的读写都需要从内存中访问。 使用…...

销售数据分析怎么做?这篇文章说清楚了

如何分析销售数据&#xff1f;分析销售数据有哪些指标&#xff1f;销售数据分析有什么作用&#xff1f; 销售数据是不是得通过数据分析软件啊&#xff1f; 本文将为您解答疑惑—— 一、分析销售数据的指标 从两个层面上来讲&#xff0c;一个是对销售情况的整体把控&#xf…...

二十六、ISIS技术总结

文章目录 ISIS 概述一、路由协议总结1、路由优先级2、分类 二、ISIS 协议特点1、特点2、ISIS 路由器的种类 三、ISIS 配置1、基础配置2、network-entity含义3、router id 和系统id转换规则 四、ISIS 开销计算1、Narrow 模式2、Wide 模式 五、 ISIS 和 OSPF 的区别 ISIS 概述 I…...

三菱m70 m80系统解密 三菱m80机床到期解锁

我们从操作系统的发展讲起&#xff0c;为什么要有线程这个概念出现。《Java多线程学习笔记(一) 初遇篇》讲Java平台下的线程&#xff0c;如何使用和创建&#xff0c;以及引入线程后所面临的问题&#xff0c;为了解决线程安全问题&#xff0c;Java引入的机制&#xff0c;这也是《…...

InnoDB 磁盘结构之数据字典和双写缓冲区

数据字典&#xff08;InnoDB Data Dictionary&#xff09; MySQL中&#xff0c;数据字典包括了: 表结构、数据库名或表名、字段的数据类型、视图、索引、表字段信息、MySQL版本信息、存储过程、触发器等内容 InnoDB数据字典由内部系统表组成&#xff0c;这些表包含用于查找表…...

Django模型层part two - 多表关系创建和多表操作

前言 继续上面一篇文章的内容&#xff0c;本文介绍多表操作。使用django ORM可以创建多表关系&#xff0c;并且也支持多张表之间的操作&#xff0c;以创建表关系和查询两部分说明django ORM的多表操作。以作者、图书、出版社和作者信息几张表作为案例进行说明。 创建表关系 …...

智能优化算法:浣熊优化算法-附代码

智能优化算法&#xff1a;浣熊优化算法 文章目录 智能优化算法&#xff1a;浣熊优化算法1.浣熊优化算法1.1 初始化1.2 阶段一&#xff1a;狩猎和攻击&#xff08;探索阶段&#xff09; 2.实验结果3.参考文献4. Matlab 摘要&#xff1a;浣熊优化算法&#xff08;Coati Optimizat…...

【51单片机】数码管显示(样例展示以及异常分析)

🎊专栏【51单片机】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【如愿】 大一同学小吉,欢迎并且感谢大家指出我的问题🥰 ⭐数码管 比如要显示“6”,那么下面图片中,AFEDCG=1,B=0 对应到数码管上,就是 ⭐原理 🎊P22~P24控制LED1~...

Android InputChannel事件发送接收系统分析

本文基于Android12。 InputChannel表示其他进程通过文件描述符传递输入事件到View的通道&#xff0c;因为需要跨进程传输&#xff0c;实现了Parcelable序列化接口&#xff0c;所以也能够理解Java层的InputChannel后面为什么使用copyTo()方法初始化。 输入事件的接收方是View&…...

Java时间类(五)-- LocalDate()类

目录 引言: 1. LocalDate的概述: 2. LocalDate的常用方法: 引言: (1)Date存在的缺陷: 如果不格式化,打印出的日期可读性差://获取当前时间Date date = new Date();System.out.println("date = " + date); //date = Wed May 03 22:30:24 CST...

用手机号码归属地 API 开发的应用推荐

引言 手机号码归属地 API是一种提供手机号码归属地信息的接口&#xff0c;通过该接口&#xff0c;可以获取手机号码所属的省份、城市、运营商等信息。它可以帮助企业更好地了解客户&#xff0c;为个性化推荐和精准广告投放提供数据支持。作为一种数据服务&#xff0c;手机号码…...

测试从业第 3 年,我看到了终点......

先说明&#xff0c;今天的内容&#xff0c;是写给想成为高级测试开发、自动化测试专家的人看的&#xff0c;因为&#xff0c;它可能颠覆你的认知。 众所周知&#xff0c;如今无论是大厂还是中小厂&#xff0c;自动化测试基本是标配了&#xff0c;毕竟像双11、618 这种活动中庞…...

结巴分词原理分析

结巴分词器工作原理 结巴分词是一款python写成的开源中文分词器&#xff0c;分词过程大致如下&#xff1a; 首先&#xff0c;结巴使用正则表达式将输入文本切割成若干中文块&#xff0c;接着对每个中文块B做处理&#xff0c;将B转成有向无环图(DAG)。DAG是以{key:list[i,j...…...

JavaEE 第三-四周

计算机Z20-第3-4周作业 总分&#xff1a;100分 得分&#xff1a;74.2分 1 . 填空题 简单 5分 在web.xml文件中&#xff0c;<url-pattern>/xxxxServlet</url-pattern>中的第一个‘/’表示__________。 学生答案 当前web应用程序的根目录 2 . 填空题 简…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发&#xff0c;实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构&#xff0c;服务器端使用Java Servlet处理请求&#xff0c;数据库采用MySQL存储信息&#xff0…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...