5. 条件和递归

5. 条件和递归

本章主要话题是if表达式, 它根据程序的状态执行不同的代码.
但首先介绍两个操作符号: 向下取整除法操作符和求模操作符.
5.1 向下取整除法操作符和求模操作符
向下取整除法操作符(//)对两个数除法运算, 并向下取整得到一个整数.
假设, 一个电影的播放时长为105分钟, 你肯能会想知道按小时算这是多长.
传统的除法会得到一个浮点数: (但是, 在写小时数时通常并不用小数点.)
>>> minutes = 105
>>> minutes / 60
1.75
向下取整除法, 则丢弃小数部分, 得到整数的小时数:
>>> minutes = 105
>>> hours = minutes // 60
>>> hours
1
要求得余数, 可以从分钟数中减去1小数:
>>> remainder = minutes - hours * 60
>>> remainder
45
另一种办法是使用求模操作符(%)将两个数相除, 得到余数:
>>> remainder = minutes % 60
>>> remainder 
45
求模操作符其实有很多实际用途. 
例如, 可以用它来检测一个数是不是另一个的倍数-如果x % y是0, 则x可以被y整除(x除以y的意思).
另外, 也可以用它来获取一个数后一位或后几位数字(这个数字是余数).
例如, x % y可以得到x的个位数(10进制).
类似地, x % 100可以获得最后两位数.如果使用的是Pythond2, 除法机制会有所不同,
除法操作符(/)在两个操作数都是整数的情况下, 实际进行的是向下取整数除法操作, 
而当两个操作数中有一个是浮点数时, 则进行的浮点数除法.
>>> 5 / 2
2
>>> 5.0 /2
2.5
>>> 5 / 2.0
2.5
5.2 布尔表达式
布尔表达式是值为真或假的表达式.
下面的例子中使用了==操作符, 来比较两个操作对象是否相等, 如果相等, 则得到True, 否则为False.
True和False是类型bool的两个特殊值, 它们不是字符串.
>>> 5 == 5
True
>>> 5 == 4
False>>> type(True)
<class 'bool'>>>> type(False)
<class 'bool'>
== 操作符是一个关系操作符, 其它的关系操作符有:
x != y   x不等于x
x > y    x大于y
x < y    x小于y
x >= y   x大于或等于y
x <= y   x小于或等于y
* 千万要注意不要写成 =>, =<.Python的操作符和数学的操作符还是有区别的, 最常见的错误是使用单等号(=)而不是双等号(==).
请注意=是一个赋值操作符, ==是一个关系操作符.
5.3 逻辑操作符
逻辑操作符有三个: and, or, not. 这些操作符的语义和他们在英语中的意思差不多.
例如, x > 0 and x < 10, 只有当x大于0且比10要小, 结果才为真, 否则为假.
n % 2 == 0 or n % 3 == 0, 当其中任意一个条件为真, 结果才为真, 否则为假.
最后, not操作符可以否定一个布尔表达式, 所以not(x > y)在x大于y时结果为假, x小于y时结果为真.
严格地说, 逻辑操作符的操作对象应该是布尔值表达式,
但是Python并不那么严格, 任何非0, 非空(None, 空字符串, 空列表... )的数都被解释为True.
>>> 42 and True
True
这种灵活性可能会很有用, 但有时候也会带一些小困惑, 
除非你很确切地知道自己在做什么, 否则因该避免使用它.
5.4 条件执行
为了编写有用的程序, 我们几乎总是需要检查条件并据此改变程序的行为. 条件语句给我们带来这种能力.
简单的形式是if表达式:
if x > 0:print('x is positive')
if之后的布尔表达式被称为条件(condition). 如果它为真, 则会执行后面缩进的语句, 否则什么都不做.
if表达式的结构和函数定义一样, 一个语句头, 接着是缩进的语句体. 这种类型的语句称为复合语句.
语句体中出现的语句数量并没有限制, 但是最少需要一行.
偶尔可能会遇到一个语句体什么都不做(通常是标记一个你还没有来得及写的代码的位置).
这个时候可以使用pass语句, pass语句什么都不做. (使用pass占位, 避免语法错误.)
if x < 0:pass  # TODO: 需要处理负责的情况.
5.5 选择执行
if语句的第二种形式是选择执行, 这种形式下, 有两种可能, 而if的条件决定哪一种运行.
语句看起来是这样的:
if x % 2 == 0:# 偶数print('x is even')else:# 奇数print('x is odd')
如果x除以2的余数是0, 则我们知道x是偶数(even), 并且程序会显示合适的消息'x is even'.
如果条件为假, 则第二段语句会运行, 因为条件必定是真假之一, 所以必然只会有一段语句运行.
这两段不同的语句成为分支(branch), 因为它们是程序执行流程中的两个支流.
5.6 条件链
有时候有超过两种可能, 所有我们需要更多的分支.
表达这种计算的一种方式是条件链(chained conditional): 
if x < y: # x小于y.print('x is less than y.')elif x > y:# x大于y.print('x is greater than y.')
else:# x和y相等.print('x and y are equal.')
elif是'else if'的缩写, 和之前一样, 只有一个分支会运行. elif语句的数量没有限制.
如果有一个else语句, 则它必须放在最后, 但也可以没有else语句.
# 前一章练习的代码片段.s
if choice == 'a':draw_a()
elif choice == 'b':draw_b()
elif choice == 'c':draw_c()
每个条件都按顺序检查, 如果第一个条件是False, 则检查下一个条件, 依次类推.
如果有一个条件为真, 则运行相应的分支, 而整个语句结束.
即使有很多个条件为真, 也只有第一个为真的分支会运行.
5.7 嵌套条件
条件判断可以再嵌套条件判断, 我们可以修改前一节中的示例, 如下:
if x == y:print('x and y are equal.')
else:if x < y:print('x is less than y.')else:print(x is greater than y.)
外侧的条件语句包含两个分支(顶格书写的语句), 第一个分支包含一行简单的语句.
第二个分支则包含了另一个if语句, 它本身也有两个分支, 
这两个分支也都是简单语句, 虽然它们其实也可以是条件语句(意思是说, 这些简单的语句可以是条件语句). 虽然语句的缩进让结构非常清晰, 但嵌套条件语句会很快随着嵌套层数增多而变得非常难以阅读, 
应该尽量避免它.
逻辑操作符常常能够用来简化嵌套条件语句. 例如, 我们可以将下面的语句替换为单独的一个条件:
if 0 < x:if x < 10:print('x is a positive single-digit number.')
对于这种类型的条件, Python还提供了一个更简洁地语法:
if 0 < x < 10:print('x is a positive single-digit number.')
5.8 递归
函数调用另外一个函数时合法的; 函数调用自己也是合法的.
这样做有什么好处可能还不明显, 但它其实是程序能做的最神奇的事情之一. 例如, 考虑下面的函数:
def countdown(n):if n <= 0:print('Blastoff!')else:print(n)countdown(n - 1)countdown(3)
如果n是0或负数, 它会输出单词'Blastoff!', 
其它情况下, 它会输出n, 并调用一个名为countdown的函数(它自己), 并传入实参n-1.
我们调用这个函数时会发生什么?countdown的执行从n=3开始, 因为n比0, 所有会输出3, 并接着调用自己...这时, countdown的执行又从n=2开始, 因为n比0, 所以会输出2, 并接着调用自己...这时, countdown的执行又从n=1开始, 因为n比0, 所以会输出1, 并接着调用自己...这时, countdown的执行又从n=0开始, 因为n不比0, 所以会输出单词'Blastoff!', 并返回.接收n=1的函数countdown返回.接收n=2的函数countdown返回.
接收n=3的函数countdown返回.然后就会到了__main__函数, 所以, 全部的输出如下:
# 运行工具窗口:
3
2
1
Blastoff!
调用自己的函数称为递归的(recursive)函数, 这个执行的过程叫作递归(recursion).
另外举一个例子, 我们可以写一个函数打印某个字符串n次.
def print_n(s, n):if n <= 0:returnprint(s)print_n(s, n - 1)print_n('s', 4)
如果n <= 0, return语句会直接退出当前函数. 执行流程会立即返回到调用者, 之后的语句不会运行.
函数另外的部分和countdown类似, 如果n大于0, 它会打印s并调用自己, 再进行n-1次显示s的操作.
所有输出行数是1 + (n - 1), 也就是n.
# 运行工具窗口显示:
s
s
s
s
对于这样简单的例子来说, 可以使用for循环会更容易.
当我们会在后面见到一些示例, 使用for循环很难写, 但使用递归则会很简单, 所以早早开始了解递归是件好事.
5.9 递归函数和栈图
3.10节中, 使用一个栈图来表示程序在进行函数调用时的状态, 同样的栈图, 可以用来帮助我们解释递归函数.
一个函数每次被调用时, Python会创建一个帧(function frame), 来包含函数的局部变量和参数.
对于递归函数, 栈上可能同时存在多个函数帧.
下图展示了countdown函数在n=3调用时的栈图.

2023-03-09_01739

和往常一样, 栈的顶端是__mian__的函数栈.
因为我们没有在__main__函数例新建任何变量或传入任何参数, 所有它是空的.4个countdown函数帧有不同的参数n, 最低端的栈, 其n=0, 被称为基准情形(base case).
因为它不再镜像递归调用, 所有后面没有其他函数帧了.
作为练习, 为函数print_n画一个栈图, 其调用的实参s='Hello'和n=2. 
然后写一个函数do_n, 接收一个函数对象和一个数字n作为形参, 他会调用给定的函数n次.

2023-03-09_01740

def print_hello(part):print(part)def do_n(func, n):if n <= 0:return do_n(func, n - 1)do_n(print_hello, 3)

2023-03-09_01741

5.10 无限递归
如果一个递归永远达不到基准情形, 则它会永远继续递归调用, 而程序也永远不停止.
这个现象被成为无限递归, 而它并不是个好主意, 下面是一个会引起无限递归的最简单函数:
def recurse():recurse()recurse()
大多数程序环境中, 无限递归的函数并不会真的永远执行, Python会在递归深度达到上限时报告一个出错消息:
Traceback (most recent call last):File "C:\Users\13600\PycharmProjects\test\test.py", line 5, in <module>recurse()File "C:\Users\13600\PycharmProjects\test\test.py", line 2, in recurserecurse()File "C:\Users\13600\PycharmProjects\test\test.py", line 2, in recurserecurse()File "C:\Users\13600\PycharmProjects\test\test.py", line 2, in recurserecurse()[Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded.
[上一行重复996]递归错误:超过最大递归深度.
当这个错误发生时, 栈上已经有1000个recurse帧了(默认值为1000, 某些电脑可能只能达到99x层.)! 
如果你不小心写出了一个无线循环, 请复查自己的函数, 确认里面至少有一个基准情况不进行递归调用.
如果已经有了一个基准情形, 检查是否已经确保在运行时能达到它.
5.11 键盘输入
目前为止我们写过的程序都不能接收用户的输入, 它们只能每次做相同的事情.
Python提供了一个内置函数input来从键盘获取输入并等待用户输入一些东西.
当用户按下回车, 程序会恢复运行, 而且input则通过字符串的形式返回用户输入的内容.
在Python 2, 这个函数叫作raw_input.
>>> text = input()
# 输入下面的字符, 结束后按下回车.
Whate are you waiting for?
>>> text
'Whate are you waiting for?'
在从用户那里获得输入之前, 最好打印一个提示信息, 告诉用户希望他们输入什么.
input函数可以接受一个参数作为提示:
>>> name = input('What ... is your name?\n')
What ... is your name?
kid
>>> name
'kid'
提示信息最后的\n表示一个换行符, 它是会引起输出显示换行的特殊字符.
这也是为何用户的输入显示在提示信息的下一行的原因.
如果希望有户输入一个整数, 可以尝试将输入值转换为int:
# 什么 .. 是空载燕子的空速?
>>> pormpt = 'What ... is the airspeed velocity of an unladen swallow?\n'
>>> speed = input(pormpt)
42
>>> int(speed)
42
但如果用户输入不是数字的话, 会得到错误:
>>> speed = input(pormpt)
What ... is the airspeed velocity of an unladen swallow?
# '你是什么意思, 非洲燕子还是欧洲燕子?'
What do you mean, an African or a European swallow?
>>> int(speed)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10:
'What do you mean, an African or a European swallow?'
后面我们会看到如何处理这种错误.
5.12 调试
当发生语法错误和运行时错误时, 出错信息包含了大量的信息, 但由时候反而会信息过量, 最有用的信息是:
* 错误的类型;
* 发生错误的地方;
语法错误通常很容易定位, 但也有辣手之处. 空格问题引起的错误很难难处理, 
因为空格和制表符都是不可以见的, 我们已经习惯与忽略它们.
>>> x = 5
>>>  y =6File "<stdin>", line 1y =6
IndentationError: unexpected indent
这个例子中, 问题的原因是第二行多缩进了一个空格.
但出错消息指向的是y, 容易误导.
总的来说, 出错消息会告诉我们发生错误的地址, 
但真正发生的地方可能在更前面的代码中, 有时候甚至在前一行.
运行时错误也是如此, 假设你想要按照分贝来计算信噪比, 公式为:SBRdb = 10lg(Psignal / Pnoise).
在python中会这么写:
import mathsignal_power = 9
noise_power = 10
# 9 // 10 = 0
ratio = signal_power // noise_power
# 0 不能作为log10方法的参数.
decibels = 10 * math.log10(ratio)
print(decibels)
在运行这个程序时, 会得到一个异常:
Traceback (most recent call last):File "C:\Users\13600\PycharmProjects\test\test.py", line 6, in <module>decibels = 10 * math.log10(ratio)
ValueError: math domain error
出错的信息指向第五行, 但那一行其实没有什么错误, 要找到真正的错误, 可能要打印出ratio的值,
结果你会发现是0. 问题出在第四行, 这个是使用向下取整除法而不是浮点数除法.
你因该花一点时间认真阅读出错信息, 但不要认为出现消息上说的每一样都对.
5.13 术语表
向下取整除法(floor division): (//)表示的操作符, 用于将两个数相除, 并对结果进行向下取整-(靠近0取整), 得到整数结果.求模操作符(modulus operator): (%)表示的操作符, 用于两个整数求模, 返回两数相除的余数.布尔表达式(booleam expression): 一种表达式, 其值是True或False.关系操作符(relationnal operator): 用来表示两个操作对象的比较关系的操作符, 如下之一:==, !=, >, <, >=, <=.条件语句(conditional statement): 依照某些条件控制程序执行流程的语句.条件(condition): 条件语句中的布尔表达式, 由它决定执行哪一个分支.复合语句(compound statement): 一个包含语句头和函数体的语句.语句头以冒号(:)结尾, 语句体相对语句头缩进一层.分支(branch): 条件语句中的一个可能性分支语句段.条件链语句(chained conditional): 一种包含多个分支的条件语句.嵌套条件语句(nested conditional): 在其它条件语句的分支中出现的条件语句.返回语句(return statement): 导致一个函数立即结束并返回到调用者的语句.递归(recursion): 在当前函数中调用自己的过程.基准情形(base case): 递归函数中的一个条件分支, 里面不会再继续递归调用.无限递归(infinite recursion): 没有基准情形的递归, 或者永远无法达到基准情形的分支的递归调用.最终, 这种无限递归会导致运行时错误.
5.14 练习
1. 练习1
time模块提供了一个函数, 名字也叫time, 它能返回从'纪元'起到当前的格林尼治时间.
'纪元'其实在认为选作基准点的时间, 在UNIX系统中, 纪元时间点是197011.
>>> import time
>>> time.time()
1678371019.427301
编写一个脚本, 读写当前时间, 并转换为一天中的小时数, 分钟数, 秒数, 以及从纪元到现在的天数.
import timenow_time = time.time()
print(now_time)  # 1678372439.8636642
# 并转换为一天中的小时数, 分钟数, 秒数. 一天的秒数(60 * 60 * 24 = 86400)
seconds_per_day = 86400# 纪元到今天的天数
day = now_time // seconds_per_day
print(day)  # 19425 天, 53年...# 求余数, 不够整除的就是今天的时间(单位为秒)
today_seconds = now_time % seconds_per_day# 现在的小时, 整除3600秒
hours_seconds = 3600
hours = today_seconds // hours_seconds# 现在的时间, 中国属于是中八区加上8.
print(hours + 8)  # 22.0 # 现在的分钟, 整除3600秒
minute = (today_seconds - hours * hours_seconds) // 60
print(minute)  # 33.0 # 现在的秒数
now_seconds = (today_seconds - hours * hours_seconds) % 60
print(now_seconds)  # 59.86366415023804
2. 练习2
费马大定理是说对于任何大于2的n, 不存在任何正整数a, b和c能够满足: a**n + b**n = c**n.
1. 编写一个函数check_fermat, 接收4个形参(即a, b, c和n)并检查费马定理是否成力,如果n比2大并且满足a**n + b**n = c**n,则程序应当打印'天哪, 费马弄错了', 否则程序应当打印'不, 那么样不行'.
def check_fermat(a, b, c, n):num1 = a ** n + b * nnum2 = c ** nprint(num1, num2) if n > 2 and num1 == num2:print('天哪, 费马弄错了')else:print('不, 那样不行')check_fermat(a=1, b=2, c=5, n=3)
2. 编写一个函数, 提示用户输入a, b, c和n的值, 将它们转换为整数,并使用check_fermat来验证它们是否违背了费马定理.
def check_fermat(a, b, c, n):num1 = a ** n + b * nnum2 = c ** nprint(num1, num2)if n > 2 and num1 == num2:print('天哪, 费马弄错了')else:print('不, 那样不行')def input_num():a_str = input('提供参a的值>>>:')b_str = input('提供参b的值>>>:')c_str = input('提供参c的值>>>:')n_str = input('提供参n的值>>>:')a = int(a_str)b = int(b_str)c = int(c_str)n = int(n_str)check_fermat(a, b, c, n)input_num()
3. 练习3
如果给你3更木棍, 你可以将它们摆成一个三角形, 也可能不可以.
例如, 如果一根木棍的长度是12英寸, 而其它两根都只有1英寸, 那么你无法让短的木棍在中间相接.
对于任意三个长度, 有一个简单的测试可以让它们是否可以组成一个三角形:
如果其中任意一个长度的值大于其它两个长度的和, 则你不能组成三角形, 否则可以.
(如果任意一个长度等于第三个, 在这儿它们组成一个'退化'的三角形.)1. 编写一个函数is_triangle, 接收是三个参数, 并根据这组长度的木棍是否能组成三角形来打印'Yes''No'.
def is_triangle(x, y, z):# 任意两边相加, 大于或等于第三边, 则可以组成三角形.if x + y >= z and x + z >= y and y + z >= x:print('Yes')else:print('No')is_triangle(3, 4, 1)  # True
2. 编写一个函数提示用户输入3根木棍的长度, 将其转换为整型, 并使用is_triangle检查这些长度的木棍是否可以组成三角形.
def is_triangle(x, y, z):# 任意两边相加, 大于或等于第三边, 则可以组成三角形.if x + y >= z and x + z >= y and y + z >= x:print('Yes')else:print('No')def stick_length():a_str = input('输入第一条木棍的长度>>>:')b_str = input('输入第一条木棍的长度>>>:')c_str = input('输入第一条木棍的长度>>>:')a = int(a_str)b = int(b_str)c = int(c_str)is_triangle(a, b, c)stick_length()
4. 练习4
下面的程序的输出是什么? 泛化一个栈图来显示程序打印结果时的状态.
def recurse(n, s):if n == 0:print(s)  # 6else:recurse(n - 1, n + s)recurse(3, 0)

2023-03-10_01742

1. 如果像recurse(-1, 0)这样调用这个函数, 会发生什么?
recurse(-1, 0)调用, 永远无法达到基准情形, 程序会无限递归调用, 最终导致运行时错误:
递归错误: 比较中超过了最大递归深度.
2. 编写一段文档字符串, 向人解释清楚要使用这个函数需要知道的东西(并且不多写其它内容).
def recurse(n, s):"""函数递归调用n次, 当n=o时结束递归, 递归时, 计算加法运算 s = n + s.:param n: int, 值必须大于0.:param s: int:return:"""if n == 0:print(s)  # 6else:recurse(n - 1, n + s)recurse(4, 0)
5. 练习5
接下来的练习需要使用第4章描述的turtle模块.
阅读下面的函数, 并看看你能否能清楚它在做什么(参考第4章中的实例), 接着运行它, 看你的理解是否真确.
import turtlebob = turtle.Turtle()def draw(t, length, n):# 递归结束条件if n == 0:return# 角度为50angle = 50# 前进为 边长*nt.fd(length * n)# 左转50度t.lt(angle)# 递归调用draw(t, length, n - 1)# 右转100度t.rt(2 * angle)# 递归调用draw(t, length, n - 1)# 左转50度t.lt(angle)# 前进 边长*nt.bk(length * n)# turtle对象, 边长, 递归次数
draw(bob, length=5, n=5)turtle.mainloop()
6. 练习6
科赫曲线(Koch curve)是一个分形, 它看起来像下图(代码后面)所示.
要绘制一个长度为x的科赫曲线不只需要做:
* 1. 绘制为x/3的科赫曲线.
* 2. 向左转60.* 3. 绘制为x/3的科赫曲线.
* 4. 向右转120.* 5. 绘制为x/3的科赫曲线.
* 6. 向左转60.* 7. 绘制为x/3的科赫曲线.
当x比3小的时候例外: 在那种清理下, 你可u直接绘制一个长度为x的直线.
1. 编写一个函数koch, 接收一个Turtle对象以及长度x作为形参, 并使用Turtle对象绘制指定长度的科赫曲线.
import turtledef koch(t, x):"""绘制科赫曲线的函数.参数:t -- Turtle对象x -- 曲线的长度返回值:None"""# 基准情形.if x < 10:t.fd(x)returnkoch(t, x / 3)t.left(60)koch(t, x / 3)t.right(120)koch(t, x / 3)t.left(60)koch(t, x / 3)# 创建一个Turtle对象
bob = turtle.Turtle()# 绘制一个长度为100的Koch曲线
koch(bob, 100)
turtle.mainloop()

image-20230310012923697

2. 编写一个函数snowflake, 绘制三条科赫曲线, 组成一个雪花形状.
解答: https://github.com/AllenDowney/ThinkPython2/blob/master/code/koch.py
import turtledef koch(t, n):if n < 10:t.fd(n)returnm = n / 3koch(t, m)t.lt(60)koch(t, m)t.rt(120)koch(t, m)t.lt(60)koch(t, m)def snowflake(t, n):for i in range(3):koch(t, n)t.rt(120)bob = turtle.Turtle()bob.pu()
bob.goto(-150, 90)
bob.pd()
snowflake(bob, 300)turtle.mainloop()

image-20230310012814773

3. 科赫曲线而已用几种方法泛化. (看一眼就得了, 国外的网站, 访问不了的.)
查看: http://en.wikipedia.org/wiki/Koch_snowflake

image-20230310013428813

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

94. 二叉树的中序遍历(Swift实现, 迭代)

题目描述 使用迭代方法解题 class TreeNode {var val: Intvar left: TreeNode?var right: TreeNode?init(_ val: Int) {self.val valself.left nilself.right nil} }func inorderTraversal(_ root: TreeNode?) -> [Int] {var result [Int]() // 用于存储中序遍历…

day37| 435. 无重叠区间 763.划分字母区间 56. 合并区间 738.单调递增的数字

文章目录 前言435. 无重叠区间思路方法一方法二 763.划分字母区间思路方法二 补充内容 重叠区间 56. 合并区间思路方法一 我自己写的方法二 教程的思路【更巧妙&#x1f636;】 738.单调递增的数字思路方法一方法二 使用list、不使用flag 总结 前言 435. 无重叠区间 注意&…

【PL理论】(22) 函数式语言:多参数 | 柯里化 (Currying) : 将多参数函数实现为返回一个函数的函数

&#x1f4ad; 写在前面&#xff1a;本章我们将继续讲解函数式语言&#xff0c;介绍多参数&#xff0c;着重讲解柯里化的概念&#xff0c;将多参数函数实现为返回一个函数的函数。 目录 0x00 多参数&#xff08;Multiple Arguments&#xff09; 0x01 柯里化&#xff08;Curr…

【车载音视频电脑】双卡式行车记录仪,带AI识别分析,支持4路AHD 1080p高清输入

一、产品外观 外观专利设计&#xff0c;铝合金材质&#xff0c;散热好、小巧、易安装&#xff1b;塑胶前面板&#xff0c;美观简洁大方&#xff0c;有独立锁。 二、产品特点 支持4路AHD高清输入1080P*30FPS、720P、D1、CIF分辨率等&#xff1b;支持接IPC&#xff0c;用网口&a…

Java | Leetcode Java题解之第149题直线上最多的点数

题目&#xff1a; 题解&#xff1a; class Solution {public int maxPoints(int[][] points) {int n points.length;if (n < 2) {return n;}int ret 0;for (int i 0; i < n; i) {if (ret > n - i || ret > n / 2) {break;}Map<Integer, Integer> map ne…

VScode中连接并使用docker容器

前提条件&#xff1a; 1.在windows下安装Docker Desktop(方法可见下面的教程) Docker Desktop 安装使用教程-CSDN博客 2.在vscode安装3个必备的插件 3.先在ubuntu中把docker构建然后运行 4.打开vscode&#xff0c;按下图顺序操作 调试好之后上传到git上&#xff0c;然后后面…

算法day29

第一题 695. 岛屿的最大面积 本题解法&#xff1a;采用bfs的算法&#xff1b; 本题使用象限数组的遍历方法和定义布尔数组vis来遍历每一个元素的上下左右元素&#xff0c;防治被遍历的元素被二次遍历&#xff1b; 本题具体分析如上题故事&#xff0c;但是由于要求区域的最大面…

5.7 Python内置函数

文章目录 1. 内置模块Aabs()all()any()ascii() Bbin()bool()bytearra()bytes() Ccallable()chr()classmethod()compile()complex() Ddelattr()dict()dir()divmod() Eenumerate()eval()exec()execfile() Ffile()filter()float()format()frozenset() Ggetattr()globals() Hhasatt…

django学习入门系列之第二点《浏览器能识别的标签3》

文章目录 列表表格往期回顾 列表 无序列表 <!-- <ul </ul> 无序列表 --> <ul><li> 内容1 </li><li> 内容2 </li><li> 内容3 </li><li> 内容4 </li> </ul>有序列表 <!-- <ol> &…

自动控制理论---零点和极点、单位脉冲响应

1、实验设备 PC计算机1台&#xff0c;MATLAB软件1套。 2、实验目的 研究四个具有相同极点分布但不同零点分布的二阶系统对单位脉冲响应的影响。绘制各系统的零点和极点分布图。计算并绘制各系统的单位脉冲响应波形。分析零点分布对单位脉冲响应的影响。 3、实验原理说明&am…

x64-linux下在vscode使用vcpkg

1.使用vscode远程连接上对应的linux &#xff0c;或者直接在图形化界面上使用。 2.安装vcpkg 插件&#xff0c;然后打开插件设置。 注意&#xff1a;defalut和host的主机一定和你自己的主机一致&#xff0c;且必须符合vcpkg三元组格式&#xff0c;其中你可以选择工作台的设置&a…

UITableView初识之分组显示数据Demo

基本介绍 继承自UIScrollView&#xff0c;因此可以滚动。 需要Datasource 遵循UITableViewDataSource协议的OC对象&#xff0c;都可以是UITableView的数据源&#xff0c;该协议中的方法告诉UITableView如何显示数据。 关于UITableView UITableView显示分组数据&#xff0c;对应…

C++设计模式——Proxy代理模式

一&#xff0c;代理模式简介 代理模式是一种 结构型设计模式&#xff0c;该模式通过引入一个新的代理对象Proxy&#xff0c;来间接访问原始对象&#xff0c;从而使访问方式变得灵活和可控。 代理对象的设定减少了客户端与真实对象之间的直接交互。 通过引入代理对象来间接访问原…

VRChat 2024年裁员原因与背景深度分析

VRChat&#xff0c;作为2022年元宇宙/VR社交领域的巨头&#xff0c;近期在2024年宣布裁员计划&#xff0c;其背后原因和背景值得业界尤其是仍在纯元宇宙虚拟空间创业的同仁们重点关注。 一、创始人决策失误 根据CEO的邮件披露&#xff0c;VRChat的创始人因缺乏经验和过度自信…

网络安全 - kali 安装

文章目录 Kali 安装教程下载镜像 Kali 安装教程 下载镜像 kali-images安装包下载_开源镜像站-阿里云 (aliyun.com) 下载对应镜像&#xff08;自己挑&#xff09; 打开本机 cmd 并输入一下命令 ipconfig找到 NAT 模式的 IP 地址并从虚拟机中 ping

【Linux】环境设置MySQL表名忽略大小写

目录 说明 一、摘要 二、查看服务器上MySQL情况 方式一&#xff1a;通过Linux方式 方式二&#xff1a;借助可视化工具&#xff08;Navicat&#xff09; 三、MySQL设置忽略表名大小写的参数&#xff08;lower_case_table_names&#xff09; 四、网上解决方案 方法一&…

基于线性核函数的SVM数据分类算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于线性核函数的SVM数据分类算法matlab仿真&#xff0c;通过程序产生随机的二维数据&#xff0c;然后通过SVM对数据进行分类&#xff0c;SVM通过编程实现&#x…

94. 二叉树的中序遍历 (Swift版本, 递归)

题目描述 使用递归方法解题 使用了一个递归函数 inorder 来进行二叉树的中序遍历&#xff0c;并将结果存储在数组 ret 中 /*** Definition for a binary tree node.* public class TreeNode {* public var val: Int* public var left: TreeNode?* public var ri…

Python | Leetcode Python题解之第149题直线上最多的点数

题目&#xff1a; 题解&#xff1a; class Solution:def maxPoints(self, points: List[List[int]]) -> int:n len(points)if n < 2:return nres 2for i in range(n):x1, y1 points[i][0], points[i][1]has {}for j in range(i 1, n):x2, y2 points[j][0], points…

x64汇编fastcall调用约定

x64汇编环境&#xff1a;只需要在x86基础上对项目属性进行设置&#xff0c;将平台设置为所有平台&#xff1b; 以及在将debug改为x64模式即可&#xff1a; 后续写完代码直接生成项目再使用本地调试器进行运行即可。 fastcall调用约定 在x64架构下&#xff0c;fastcall调用约定…