【数据结构】(Python)差分数组。差分数组与树状数组结合

差分数组:

  • 基于原数组构造的辅助数组。
  • 用于区间修改、单点查询。区间修改的时间复杂度O(1)。单点查询的时间复杂度O(n)。
  • 差分数组的元素:第一个元素等于原数组第一个元素,从第二个元素开始是原数组对应下标的元素与前一个元素的差(即原数组相邻元素的差)。
  • 区间修改:通过修改差分数组中区间的两端点,可快速地修改原数组中整个区间的值。具体操作:修改差分数组中起始下标的元素,恢复结束下标的后一个元素。
  • 单点查询:通过差分数组查询原数组中的元素。具体操作:差分数组中从开头到对应下标元素的累和(前缀和)。
  • 注:① 差分与前缀和互为逆运算(差分数组是原数组的差分,原数组是差分数组的前缀和)② 本文原数组为a,差分数组为d,下标均从0开始。
  • 补充:二维差分数组,类似一维差分数组,注意行和列。
  • 补充:差分数组结合树状数组,可提高效率,也可实现区间修改、区间查询

 


差分数组的元素:

  • 差分数组的第一个元素(下标0):原数组的第一个元素(下标0)。即d[0]=a[0]。
  • 差分数组的下标i 的元素:原数组的下标i 的元素与前一个元素的差。即d[i]=a[i]-a[i-1]。
# a为原数组,d为差分数组
n = len(a)
d = [0] * n        # 差分数组初始化
d[0] = a[0]
for i in range(1, n):d[i] = a[i] - a[i - 1]

aa097780b3194d5cabbb07b91a0cb283.png

 


区间修改:区间[l,r]

通过修改差分数组中区间的两端点,可快速修改原数组中整个区间的值。

  • 目标:原数组下标l到下标r都修改。例如:区间[l,r]的元素都+val,即a[l]+val,a[l+1]+val,...,a[r]+val。
  • 具体操作:修改差分数组中区间两端点的值,即差分数组下标l修改、下标r+1恢复。例如:d[l]+val,d[r+1]-val。

此处,区间修改由update函数实现。参数:l为区间起始(左侧)下标,r为区间结束(右侧)下标,val为值(例如:增加的值)。

def update(l:int, r:int, val:int):"""区间修改。l为区间起始(左侧)下标,r 为区间结束(右侧)下标,val为值"""d[l] += vald[r + 1] -= val

91f6cba6118542bb9c807b4546aefb01.png

 


单点查询(前缀和):

通过差分数组,查询原数组中的元素。

  • 方法一:前缀和。原数组下标i 的元素为差分数组从下标0到下标i 的元素累和。即a[i]=d[0]+d[1]+...+d[i]。
  • 方法二:原数组下标i 的元素为原数组下标i-1 的元素加上差分数组下标i 的元素。即a[i]=a[i-1]+d[i]。
  • 注:原数组第一个元素等于差分数组第一个元素,即a[0]=d[0]。

此处,单点查询由query函数实现。参数:i为下标。

# 方法一:前缀和
def query(i:int):"""单点查询。i为下标,ans为合计"""ans = 0while i >= 0:ans += d[i]i -= 1return ans# 方法二
a[0] = b[0]
# n为数组长度
for i in range(1, n):a[i] = a[i - 1] + d[i]

620ffe09f9654241abaca72afb893f96.png

 


补充:二维差分数组:

注:为了便于二维差分数组的理解,此处,二维原数组第一行(行下标0)和第一列(列下标0)的元素均为0。对应二维差分数组的第一行(行下标0)和第一列(列下标0)的元素也均为0。

1、二维差分数组的元素:

# a为二维原数组,d为二维差分数组
n = len(a)            # 矩阵行数
m = len(a[0])         # 矩阵列数
for i in range(1, n):for j in range(1, m):d[i][j] = a[i][j] - a[i - 1][j] - a[i][j - 1] + a[i - 1][j - 1]

4190b28bb74c4c23b96749da3004f4a8.png

 

2、二维差分数组的区间修改:

通过修改差分数组矩阵端点的值,修改原数组整个矩阵区间的值。

def update(i1:int, j1:int, i2:int, j2:int, val:int)"""(矩阵)区间修改。(i1,j1)为矩阵起始位置,(i2,j2)为矩阵结束位置"""d[i1][j1] += vald[i2 + 1][j1] -= vald[i1][j2 + 1] -= vald[i2 + 1][j2 + 1] += val

6ce594639ac94ce0897c9308523af62e.png

 

3、二维差分数组的单点查询(前缀和):

通过差分数组,获取原数组中的元素。

  • 方法一:原数组(i, j)的值为从差分数组开头位置(0, 0)到对应位置(i, j)的所有元素的总和。即a[i][j]=d[0][0]+d[0][1]+...+d[0][j]+d[1][0]+d[1][1]+...+d[1][j]+...+d[i][0]+d[i][1]+...+d[i][j]。
  • 方法二:原数组(i, j)的值为原数组前一行(i-1,j)和原数组前一列(i, j-1)与差分数组中(i, j)的总和。但因原数组(i-1, j)和原数组(i, j-1)两个元素均加上了原数组(i-1, j-1)的值,需减除多加的一次。即a[i][j]=a[i- 1][j] + a[i][j - 1] - a[i - 1][j - 1] + d[i][j]。
def query(i:int, j:int, a:list):"""查询原数组的值。i为行下标,j为列下标,a为原数组"""return a[i- 1][j] + a[i][j - 1] - a[i - 1][j - 1] + d[i][j]

ec55ebd36cdb4392a00eaad833e6b2b9.png

 


案例:【力扣】

(难度:中等)1109. 航班预订统计

c84fb0f693ef4ddd84ce5ce515164496.png

【Python3】设置差分数组(元素都为0),使用差分数组修改航班区间两端点进行修改整个区间,再计算差分数组的前缀和。

注意:航班编号从1开始,差分数组下标从0开始。

class Solution:def corpFlightBookings(self, bookings: List[List[int]], n: int) -> List[int]:# 差分数组d = [0] * nfor l, r, val in bookings:d[l - 1] += valif r < n:d[r] -= val# 计算差分数组的前缀和res = [0] * nres[0] = d[0]for i in range(1, n):res[i] = res[i - 1] + d[i]return res

可以在差分数组的基础上直接计算前缀和,无需额外占用内存空间开辟新数组。

class Solution:def corpFlightBookings(self, bookings: List[List[int]], n: int) -> List[int]:# 差分数组d = [0] * nfor l, r, val in bookings:d[l - 1] += valif r < n:d[r] -= val# 在差分数组的基础上,直接计算前缀和for i in range(1, n):d[i] += d[i - 1]return d

注:差分数组结合树状数组,可提高效率。题解详见本文“差分数组和树状数组的结合”中的案例。

 

(难度:困难)1526. 形成目标数组的子数组最少增加次数

cb7a8842a6dc4551a9fefda8fc9c0e82.png

【Python3】

解题思路:反向思考,使用差分数组将目标数组的所有元素都变为0。差分数组中的元素都变为0,则对应目标数组的元素也都为0。(因目标数组中的元素是差分数组中元素的前缀和)

  • 根据提示,已知目标数组的元素都为正数,则其差分数组的合计(即目标数组中最后一个元素)一定为正数。
  • 差分数组的第一个元素(即目标数组的第一个元素)也一定为正数。差分数组的其他元素值(差分值)若为负数,则其左侧必定有差分值为正数。
  • 区间修改时,修改差分数组中区间起始下标的值和恢复区间结束下标后一个的值。本题中差分数组的区间起始下标的值减1,区间结束下标后一个的值加1。

本题,统计操作次数即为统计差分值为正数的总和。

  • 若差分值是正数,正数是多少 就操作多少次(每次减1),最终变为0。
  • 若差分值为负数,则其左侧的正数差分值减1的同时 其会加1,最终变为0,无需统计操作次数。
  • 若正数差分值的合计比负数差分值的合计多,则多的正数差分值减1时,虚拟的(不存在)下标n的值加1。
  • 因差分数组的合计为正数,则不存在负数差分值的合计比正数差分值的合计多。

3acae12812c442ac94ffd371737202cd.png

class Solution:def minNumberOperations(self, target: List[int]) -> int:n = len(target)# 差分数组d = [0] * n       # 差分数组初始化d[0] = target[0]for i in range(1, n):d[i] = target[i] - target[i - 1]# 统计操作次数(统计差分值为正数的总和)ans = 0# 遍历差分数组for i in range(n):# 差分值为正数,则为该元素变为0的操作次数ans += max(d[i], 0)return ans

(简化) 可以不额外占用内存开辟差分数组。可以遍历目标数组时,依次计算对应的差分值,并判断且统计操作次数。时间复杂度O(n),空间复杂度O(1)。

class Solution:def minNumberOperations(self, target: List[int]) -> int:n = len(target)# ans统计操作次数,初始为目标数组第一个元素值ans = target[0]# 从下标1开始遍历目标数组,获取对应下标的差分值for i in range(1, n):# 差分值为正数,则为该元素变为0的操作次数ans += max(target[i] - target[i - 1], 0)return ans

 


差分数组和树状数组的结合:

差分数组中,区间修改的时间复杂度为O(1),但单点查询的时间复杂度O(n)。为提高查询的效率,结合树状数组,时间复杂度为O(logn)。

  1. 原数组a通过差分获得差分数组d。
  2. 通过树状数组t的单点修改(树状数组维护)来维护差分数组d。
  3. 使用差分数组的区间修改,而差分数组的区间两端点的修改都通过树状数组的单点修改来完成。
  4. 使用树状数组的单点查询(前缀和)获得差分数组的前缀和即原数组中的元素,以此实现差分数组的单点查询。
  5. 补充:若再额外维护一个数组e,可使用树状数组的单点查询(前缀和)获取原数组的前缀和,实现区间查询。
  6. 注意:原数组a、差分数组d、数组e的下标从0开始,树状数组下标从1开始。

 1、差分数组(初始化,维护差分数组的元素)

# 差分数组初始化
n = len(a)
d = [0] * n
# 维护差分数组的元素
d[0] = a[0]
for i in range(1, n):d[i] = a[i] - a[i - 1]

2、树状数组(初始化,维护树状数组的元素)

  • 树状数组下标从1开始,为方便操作,树状数组长度n+1(下标0存在但不使用)。
  • 差分数组下标 i,树状数组下标 i+1。
  • 使用树状数组维护差分数组,此时参数val为差分数组的元素。
  • 即树状数组维护差分数组update(i+1,d[i])。
# 树状数组
n = len(a)
t = [0] * (n + 1)         # 树状数组初始化,下标从1开始(为方便操作,下标0存在但不使用)# 树状数组的单点修改(使用树状数组维护差分数组,因此,val为差分数组的元素)
def update(i:int, val:int):"""树状数组中的单点修改(树状数组维护)"""while i <= n:t[i] += vali += i & -i        # lowbit函数:i & -i,此处未单独设置函数# 实际维护执行
for i in range(n):update(i + 1, d[i])    # 树状数组下标从1开始

3、差分数组的区间修改(通过树状数组的单点修改完成)

差分数组的区间修改,只需修改差分数组中的区间两端点。而此处,区间两端点则都通过树状数组的单点修改完成。

注意下标。

# 差分数组的区间修改:(区间[l,r],修改值val)
# 此处区间为树状数组对应的下标,而差分数组对应区间为[l-1, r-1]
update(l, val)
update(r + 1, -val)

  4、树状数组的前缀和(获取原数组中的元素)

通过树状数组的前缀和(区间查询,区间[1,i])来获得差分数组的前缀和,而差分数组的前缀和为原数组中的元素。

以此实现差分数组的单点查询。

  • 差分数组下标 i,树状数组下标 i+1。
# 树状数组的前缀和(区间查询,区间[1,i])
def query(i:int):"""树状数组中计算前缀和"""ans = 0while i > 0:ans += t[i]i -= i & -i            # lowbit函数:i & -i,此处未单独设置函数return ans# 实际查询执行
a[i] = query(i + 1)            # 查询原数组中下标i的值

 案例:【力扣】

(难度:中等)1109. 航班预订统计

c84fb0f693ef4ddd84ce5ce515164496.png

【Python3】差分数组和树状数组结合。即使用树状数组维护差分数组,使用差分数组的区间修改来快速修改整个区间的元素(通过树状数组的单点修改完成),再通过树状数组计算前缀和。

# 类BIT(即树状数组)
class BIT:def __init__(self, n:int):self.n = nself.t = [0] * ndef update(self, i:int, val:int):"""单点修改"""while i < self.n:self.t[i] += vali += i & -i           # lowbit函数:i & -i。此处未单独设置函数 def query(self, i:int):"""前缀和"""ans = 0while i > 0:ans += self.t[i]i -= i & -i           # lowbit函数:i & -i。此处未单独设置函数return ansclass Solution:def corpFlightBookings(self, bookings: List[List[int]], n: int) -> List[int]:# 使用树状数组维护差分数组(初始元素都为0)bitree = BIT(n + 1)# 差分数组的区间修改(使用树状数组的单点修改完成)for l, r, val in bookings:# 修改差分数组的区间起始的元素bitree.update(l, val)# 恢复区间结束的下一个元素。若区间结束元素是差分数组的最后一个元素,则无需恢复if r < n: bitree.update(r + 1, -val)# 差分数组的前缀和res = [0] * nfor i in range(n):res[i] = bitree.query(i + 1)return res

 

补充:5、额外维护数组e(可获取原数组的前缀和)

使用两个树状数组分别维护差分数组和数组e,可实现区间修改、单点查询、区间查询。

3d67fb5f76c6460eb101e6b359da5d88.png

  1. 原数组a通过差分获得差分数组d,并初始化数组e。
  2. 使用树状数组分别维护差分数组d和数组e。
  3. 区间修改,差分数组的区间两端点的修改都通过树状数组的单点修改来完成。同时数组e的区间也要做相应修改。
  4. 使用树状数组的单点查询(前缀和)获得差分数组的前缀和即原数组中的元素,以此实现单点查询。
  5. 使用树状数组的单点查询(前缀和)获得原数组的前缀和,以此实现区间查询。

因:原数组的前缀和:s[i] = a[0] + a[1] +...+ a[i]

        差分数组的前缀和(原数组的元素):a[i] = d[0] + d[1] +...+ d[i]

因此:s[i] = a[0] + a[1] +...+ a[i]

                 = d[0] + (d[0] + d[1]) + ...+ (d[0] + d[1] +...+ d[i])

                 = (i+1)* (d[0] + d[1] +...+ d[i]) - (0 * d[0] + 1 * d[1] + ...+ i * d[i])

                 = eq?%28i%20&plus;%201%29%20*%20%5Csum%20d%5Bi%5D%20-%20%5Csum%20i%20*%20d%5Bi%5D

其中,eq?%5Csum%20d%5Bi%5D为差分数组的前缀和,则维护额外的数组e(元素为 i * d[i]),获取数组e的前缀和。

注意:原数组a和差分数组d和数组e下标从0开始。而树状数组下标从1开始,注意实际对应下标。

 (5-1)差分数组d和数组e的初始化,以及维护差分数组元素

# 差分数组d和数组e初始化,a为原数组
n = len(a)
d = [0] * n
e = [0] * n# 维护差分数组元素
d[0] = a[0]
for i in range(1, n):d[i] = a[i] - a[i - 1]

(5-2)两个树状数组的初始化,以及使用树状数组维护差分数组d和数组e

  • 两个树状数组分别用于维护差分数组(元素d[i])和数组e(元素 i * d[i])。
  • 差分数组和数组e下标 i,树状数组下标 i+1。
# 两个树状数组初始化
n = len(a)
t1 = [0] * (n + 1)         # 用于维护差分数组d
t2 = [0] * (n + 1)         # 用于维护数组edef update(i:int, val:int, t:list):"""树状数组中的单点修改(树状数组维护)"""while i <= n:             # 此处,树状数组的长度为n+1,最后一个元素下标为nt[i] += val           # t为树状数组i += i & -i           # lowbit函数:i & -i,此处未单独设置函数# 实际维护执行
# 差分数组和数组e的下标都从0开始,树状数组下标从1开始
for i in range(n):update(i + 1, d[i], t1)                # 维护差分数组dupdate(i + 1, d[i] * i, t2)            # 维护数组e

(5-3)差分数组的区间修改(使用树状数组的单点修改完成)

  • 树状数组区间[l,r],树状数组修改下标 l 和下标 r+1。
  • 即差分数组和数组e对应区间[l-1, r-1],差分数组和数组e中对应修改 下标 l-1 和下标 r。
  • 注意:数组e的元素为d[i]*i。差分数组修改的同时,数组e也修改,且数组e的修改值需乘以对应下标 i 。
# 差分数组的区间修改(使用树状数组的单点修改完成),区间[l,r]
# 树状数组下标从1开始,原数组和差分数组和数组e下标从0开始。
# 此处区间为树状数组对应的下标,而差分数组和数组e对应区间为[l-1, r-1]
update(l, val, t1)
update(r + 1, -val, t1)
update(l, val * (l - 1), t2)       # 树状数组下标为l,而数组e对应下标为l-1
update(r + 1, -val * r, t2)        # 树状数组下标为r+1,而数组e对应下标为r

 (5-4)前缀和(获取原数组中的元素,以及获取原数组的前缀和)

  1. 通过树状数组获取差分数组的前缀和,差分数组的前缀和为原数组中的元素,即a[i] = d[0]+d[1]+...+d[i]。
  2. 通过树状数组获取原数组的前缀和,即eq?s%5Bi%5D%20%3D eq?%28i%20&plus;%201%29%20*%20%5Csum%20d%5Bi%5D%20-%20%5Csum%20i%20*%20d%5Bi%5D,此公式 i 从0开始。
  3. 原数组下标 i,树状数组下标 i+1。
def query(i:int, t:list):"""树状数组中计算前缀和"""ans = 0while i > 0:ans += t[i]           # t为树状数组i -= i & -i           # lowbit函数:i & -i,此处未单独设置函数return ans# 树状数组下标从1开始,原数组和差分数组和数组e下标从0开始
# 实际获取原数组的值
for i in range(n):a[i] = query(i + 1, t1)# 实际获取原数组的前缀和
for i in range(n):s[i] = (i + 1) * query(i + 1, t1) - query(i + 1, t2)

 (5-5)区间和(获取原数组的区间和)

获取原数组的区间[l,r]的元素和,即s[l,r]=s[r]-s[l-1]。

因树状数组下标从1开始,原数组下标从0开始。对应树状数组的区间为[l+1,r+1]。

def range_query(l:int, r:int):"""获取原数组的区间[l,r]的元素和,s[l,r]=s[r]-s[l-1]"""# 原数组下标从0开始,树状数组下标从1开始。树状数组对应区间[l+1,r+1]return (r + 1) * query(r + 1, t1) - query(r + 1, t2) - (l * query(l, t1) - query(l, t2))

 具体的树状数组知识点:树状数组

 

【Python】代码示例:

注:原数组a、差分数组d、数组e的下标从0开始,树状数组下标从1开始。

# 类BIT(即树状数组)
class BIT:def __init__(self, n):self.n = nself.t = [0] * ndef update(self, i, val):"""单点修改(树状数组维护)"""while i < self.n:           # 此处,树状数组的长度为n,最后一个元素下标为n-1self.t[i] += vali += i & -idef query(self, i):"""前缀和,区间[1,i]"""ans = 0while i > 0:ans += self.t[i]i -= i & -ireturn ans# 主程序
def main():a = [5,2,6,1,7,9]n = len(a)# 打印原数组的元素print(f"原数组:                ", end="")for i in range(n):print(a[i], end="    ")print()# 差分数组dd = [0] * nd[0] = a[0]for i in range(1, n):d[i] = a[i] - a[i - 1]# 打印差分数组的元素print(f"差分数组:              ", end="")for i in range(n):print(d[i], end="    ")print()# 数组e(元素:d[i] * i)e = [0] * n# 使用树状数组维护差分数组d和数组et1 = BIT(n + 1)t2 = BIT(n + 1)for i in range(n):t1.update(i + 1, d[i])t2.update(i + 1, d[i] * i)# 假设:原数组区间[1,3]都加10,修改差分数组的树状数组和数组e的树状数组# 树状数组对应区间[2,4]t1.update(2, 10)            # (差分数组)修改区间起始下标的元素t1.update(5, -10)           # (差分数组)修改区间结束下标的后一个元素t2.update(2, 10 * 1)        # (数组e)修改区间起始下标的元素t2.update(5, -10 * 4)       # (数组e)修改区间结束下标的后一个元素# 打印修改后原数组中所有元素(即差分数组的前缀和)print(f"修改后差分数组的前缀和:", end="")for i in range(n):a[i] = t1.query(i + 1)print(a[i], end="    ")print()# 获取原数组中下标2的元素print(f"原数组中下标2的元素:{a[2]}")# 打印修改后数组e的前缀和print(f"修改后数组e的前缀和:   ", end="")for i in range(n):e[i] = t2.query(i + 1)print(e[i], end="    ")print()# 获取原数组中下标2的前缀和print(f"修改后原数组的前缀和:  ", end="")s = [0] * n                # 记录原数组的前缀和for i in range(n):s[i] = (i + 1) * t1.query(i + 1) - t2.query(i + 1)print(s[i], end="    ")print()print(f"原数组中下标2的前缀和:{s[2]}")# 获取原数组中区间和,区间[2,5]rq = s[5] - s[1]print(f"原数组中区间和,区间[2,5]:{rq}")# 主程序执行
main()

执行结果如下:

73766bef162e4c3982e0c572248702e3.png

 

 

 

 

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

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

相关文章

修复OpenHarmony系统相机应用横屏拍照按钮点不到的问题

适配OpenHarmony系统相机应用横屏UI&#xff0c; 相关pr: https://gitee.com/openharmony/applications_camera/pulls/233/files 适配效果 如何安装 编译好的hap提供在附件中 1.预置在源码&#xff0c;随固件安装 2.安装hap hdc shell "mount -o remount,rw /"…

10-Gin 文件上传 --[Gin 框架入门精讲与实战案例]

使用 Gin 框架处理文件上传是一个常见的任务&#xff0c;Gin 提供了简单而直观的方法来处理文件上传。下面将介绍如何用 Gin 实现文件上传功能。 1. 安装 Gin 如果你还没有安装 Gin&#xff0c;可以通过 Go 的包管理工具 go get 来安装&#xff1a; go get -u github.com/gi…

Promise实现原理解析,及实现方法。

Promise原理解析 Promise的介绍原理分析源码实现发布部分全部代码订阅部分基础代码简单发布订阅完整代码测试订阅能力链式调用的实现完整链式调用代码链式调用Promise完整功能代码 Promise的介绍 一&#xff0c;Promise的理解 在JavaScript中&#xff0c;Promise是一种用于处理…

http报头解析

http报文 http报文主要有两类是常见的&#xff0c;第一类是请求报文&#xff0c;第二类是响应报文&#xff0c;每个报头除了第一行&#xff0c;都是采用键值对进行传输数据&#xff0c;请求报文的第一行主要包括http方法&#xff08;GET&#xff0c;PUT&#xff0c; POST&#…

【日常开发】Git Stash使用技巧

文章目录 引言一、git stash 基础命令&#xff08;一&#xff09;存储当前工作区的修改&#xff08;二&#xff09;查看存储列表 二、查看存储的内容&#xff08;一&#xff09;查看特定存储的详细内容&#xff08;二&#xff09;查看特定存储修改的文件列表 三、恢复存储的修改…

微服务保护-sentinel

为什么要有微服务保护&#xff1f; 微服务保护是为了避免微服务雪崩而出现的&#xff0c;每个微服务能处理的请求是有限的&#xff0c;如果一个微服务出现问题导致一个请求进入微服务的时间太久&#xff0c;就会导致大量去请求停滞在微服务内部&#xff0c;这样就会过分占用系统…

【Redis】Redis 典型应用 - 缓存 (cache)

目录 1. 什么是缓存 2. 使用 Redis 作为缓存 3. 缓存的更新策略 3.1 定期生成 3.2 实时生成 4. 缓存的淘汰策略 5. 缓存预热, 缓存穿透, 缓存雪崩 和 缓存击穿 关于缓存预热 (Cache preheating) 关于缓存穿透 (Cache penetration) 关于缓存雪崩 (Cache avalanche) 关…

关于easy-es对时间范围查询遇到的小bug

前言&#xff1a;在使用easy-es之前作为一个小白的我只有es原生查询的基础&#xff0c;在自己通过查看官方文档自学easy-es遇到了一个挫折&#xff0c;其他的还好语法和MybatisPlus差不多&#xff0c;正以为我觉得很快就能入手&#xff0c;在对时间范围的判断就给我当头一棒&am…

从0到机器视觉工程师(一):机器视觉工业相机总结

目录 相机的作用 工业相机 工业相机的优点 工业相机的种类 工业相机知名品牌 光源与打光 打光方式 亮暗场照明 亮暗场照明的应用 亮暗场照明的区别 前向光漫射照明 背光照明 背光照明的原理 背光照明的应用 同轴光照明 同轴光照明的应用 总结 相机的作用 相机…

HTML——53. 创建表单

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>创建表单</title></head><body><!--form标签用于创建一个表单&#xff0c;会将里面的内容一起发送服务器&#xff0c;其结构类似于表格--><!--表…

逐行讲解大模型流式输出 streamer 源码

目录 简介TextStreamer 基础流式输出TextIterateStreamer 迭代器流式输出本地代码模型加载并前端展示streamlit 输出显示gradio 输出显示 vllm 部署模型并前端展示streamlit 输出显示gradio 输出显示 备注 简介 本文详细讲解了大模型流式输出的源码实现&#xff0c;包括TextSt…

java_使用阿里云oss服务存储图片

什么情况下可以使用阿里云oss服务存储图片&#xff1f; 对图片的访问速度有高要求时使用&#xff0c;方便用户快速的&#xff08;比如在网页页面中&#xff09;访问到图像 参考&#xff1a;41 尚上优选项目-平台管理端-商品信息管理模块-阿里云OSS介绍_哔哩哔哩_bilibili 1.…

第5章 共享内存范式:C语言层面

5.1OpenMP 5.1.1OpenMP的介绍 OpenMP三个原则 5.2OpenMP的使用 编译制导指令以#pragma omp 开始&#xff0c;后边跟具体的功能指令&#xff0c;格式如:#pragma omp 指令[子句[,子句].]。常用的功能指令如下: 5.2.1编译制导 5.2.2API和环境变量 具体案例-邻接矩阵 // 本代码…

web 开发全局覆盖文件上传身份验证漏洞利用

全局覆盖 首先认识全局变量和局部变量 再一个就是知道全局变量是全局使用的并且有个特点就是可以覆盖 这个就是全局变量我们输出一下发现 z居然等于函数内的计算值 把我们原来定义的全局变量 $z给覆盖了 看一下局部变量 这个时候 z就不会被覆盖 <?php $x1; $y2; …

No.2十六届蓝桥杯备战|练习题4道|数据类型|字符型|整型|浮点型|布尔型|signed|unsigned(C++)

B2002 Hello,World! - 洛谷 #include <iostream> using namespace std; int main() { cout << "Hello,World!" << endl; return 0; }打印飞机 #include <iostream> using namespace std;int main() {cout << " …

46. Three.js案例-创建颜色不断变化的立方体模型

46. Three.js案例-创建颜色不断变化的立方体模型 实现效果 知识点 Three.js基础组件 WebGLRenderer THREE.WebGLRenderer是Three.js提供的用于渲染场景的WebGL渲染器。它支持抗锯齿处理&#xff0c;可以设置渲染器的大小和背景颜色。 构造器 antialias: 是否开启抗锯齿&am…

5.系统学习-PyTorch与多层感知机

PyTorch与多层感知机 前言PyTroch 简介张量&#xff08;Tensor&#xff09;张量创建张量的类型数据类型和 dtype 对应表张量的维度变换&#xff1a;张量的常用操作矩阵或张量计算 Dataset and DataLoaderPyTorch下逻辑回归与反向传播数据表格 DNN&#xff08;全连结网络&#x…

WPF中的Microsoft XAML Behaviors包功能详解

什么是XAML Behaviors(行为) XAML Behaviors 提供了一种简单易用的方法&#xff0c;能以最少的代码为 Windows UWP/WPF 应用程序添加常用和可重复使用的交互性。 但是Microsoft XAML Behaviors包除了提供常用的XAML Behaviors之外&#xff0c;还提供了一些Trigger&#xff08…

Soildstate渗透测试

第一步&#xff1a;信息收集 Arp-scan -l 扫描本地存活ip&#xff0c;发现可疑ip 192.168.52.140 使用nmap -T4 -sV -sC -p- 192.168.52.140 对目标进行全端口扫描 同时使用dirb和dirsearch对目标网址进行目录爆破&#xff0c;这些网址都可以点进去看看进行一下信息收集看看是…

HTTP cookie与session

telnet命令 telnet 是一个网络协议&#xff0c;用于通过 TCP/IP 网络进行远程登录到服务器。它允许用户在本地计算机上通过网络连接到远程服务器&#xff0c;并在服务器上执行命令 telnet [主机名或IP地址] [端口号]//连接服务器 在 telnet 会话中&#xff0c;Ctrl] 会将你从…