1、给一个半径,求圆的面积和周长。圆周率3.14
import math
# 从用户获取圆的半径,并将其转换为整数
radius = int(input('radius = '))
# 计算圆的面积。公式为 pi * r^2
area = math.pi * radius ** 2
# 打印圆的面积,保留两位小数
print("area = {:.2f}".format(area))
# 计算圆的周长。公式为 2 * pi * r
print('circumference =', math.pi * 2 * radius)
2、输入两个数,比较大小后,从小到大升序打印
# 提示用户输入第一个数,并将输入的字符串转换为整数后存储在变量a中
a = int(input("first="))
# 提示用户输入第二个数,并将输入的字符串转换为整数后存储在变量b中
b = int(input("second="))
# 使用if语句来比较a和b的大小
if a > b:
# 如果a大于b,则打印b和a,这里使用print函数打印两个数,
# 并用逗号分隔,打印出来的形式会是"b,a",其中b是较小的数,a是较大的数
print(b, a)
else:
# 如果a不大于b(即a小于等于b),则打印a和b,打印出来的形式会是"a,b",
# 其中a是较小的数,b是较大的数或者两者相等
print(a, b)
或者
# 获取用户输入并转换为整数,存储在变量a中
a = int(input('请输入第一个整数: '))
# 获取用户输入并转换为整数,存储在变量b中
b = int(input('请输入第二个整数: '))
# 使用条件表达式来比较a和b的大小,并打印结果
# 如果a大于b,则打印 b, a,否则打印 a, b
print(b, a) if a > b else print(a, b)
3、依次输入若干个整数,打印出最大值。如果输入为空,则退出程序
# 请求用户输入一个数字作为初始最大值,并将输入转换为整数类型存储在变量m中
m = int(input('Input your first number:'))
# 开始一个无限循环,以便持续接收用户的输入
while True:
# 提示用户输入一个数字,并将输入存储在变量c中
c = input('Input a number:')
# 检查用户是否输入了数字
if c:
# 将输入转换为整数类型,并存储在变量n中
n = int(c)
# 判断用户输入的数字n是否大于当前的最大值m
if n > m:
# 如果n大于m,则更新最大值m为n
m = n
# 打印当前的最大值m
print('Max is', m)
else:
# 如果用户没有输入任何内容(直接按回车),则打印"Exit."并退出循环
print('Exit.')
break
4、给定一个不超过5位的正整数(不转换为字符串),判断该数的位数,依次打印出万位、千位、百位、十位、个位的数字
难点在于如何对一个正整数进行迭代处理(暂不考虑使用字符串
假设有数字54321,目标打印出5、4、3、2、1。
第一循环 54321 // 10000 =5 54321 % 10000 =5
第二循环 4321 // 1000 =4 4321 % 1000 =4
第三循环 321 // 100 =3 321 % 100 =3
第四循环 32 // 10 =2 32 % 10 =2
第五循环 1 // 1 =1 1 % 1 =1
每一次循环中,整除就能获得最高位置的数,取模就能获得出去最高位的数的剩余数字,且取模后的数字作为下一趟的待处理数字。
# 假设c是一个不超过5位的整数
c = int('54321') # 不超过5位数
# 定义一个权重w,初始值为10000,用于从右至左提取每一位数字
w = 10000
# 循环5次,因为c最多有5位
for i in range(5):
# 通过整数除法(//),我们得到c除以w的商,这实际上是提取了c的最高位数字
x = c // w
# 使用模运算(%),我们得到c除以w的余数,这是去除了最高位数字后的新c
c = c % w
# 打印提取的数字
print(x)
# 将权重w除以10,以便在下一次迭代中提取下一个数字
w //= 10
或者
# 将字符串'54321'转换为整数并赋值给c,这里的c不会超过5位数
c = int('54321') # 不超过5位数
# 定义一个权重w,初始值为10000,用于从c中提取每一位数字
w = 10000
# 循环5次,以提取c的每一位数字
for i in range(5): # 计算第四次后,余数就是个位数
# 使用整数除法得到商,即c的当前最高位数字,并赋值给x
x = c // w
# 使用模运算得到余数,即去除了当前最高位数字后的新c
c = c % w
# 打印提取的数字x
print(x)
# 将权重w除以10,以便在下一次迭代中提取下一个数字
w //= 10
else:
# 循环结束后,打印c的余数,如果c是5位数,则余数为0,否则余数为c的最低位数字
print(c) # 余数
或者
# 将字符串'54321'转化为整数,并赋值给c。此处假设c不超过5位数
c = int('54321')
# 设置一个权重为10000,用于从c中提取每一位数字
w = 10000
# 假设数字长度为5,用于记录最终提取出来的非零数字的长度
length = 5
# 初始化一个标记flag为False,用于判断是否找到了第一个非零数字
flag = False
# 循环5次,用于提取c中的每一位数字
for i in range(5):
# 通过整数除法提取c的最高位数字,并赋值给x
x = c // w
# 如果还没有找到第一个非零数字
if not flag:
# 如果x非零,说明找到了第一个非零数字
if x:
flag = True # 打标记,表示已经找到第一个非零数字
else:
length -= 1 # 如果x为0,则在找到第一个非零数字前遇到了零,减少length的值
# 如果已经找到了第一个非零数字,则打印x
if flag:
print(x)
# 通过模运算去掉c的最高位数字,用于下一次循环提取下一个数字
c = c % w
# 将权重w除以10,用于下一次循环提取下一个数字
w //= 10
# 打印最终提取出来的数字的长度
print('The length of the number is', length)
5、输入n个数,求每次输入后的算数平均数
# 初始化变量s用于存储输入数字的和
s = 0 # 和
# 初始化变量n用于存储输入数字的次数
n = 0 # 次数
# 无限循环,等待用户输入
while True:
# 接收用户输入,并存储在变量i中
i = input('>>')
# 判断用户输入是否为'quit',如果是,则退出循环
if i == 'quit':
break
# 用户输入不是'quit',则输入次数n加1
n += 1
# 将用户输入转换为整数,并累加到s中
s += int(i)
# 计算当前平均值
avg = s / n
# 打印当前平均值
print(avg)
6、打印一个边长为n的空心正方形
# 设置菱形的大小
n = 5
# 使用字符'*'来绘制菱形
char = '*'
# 打印菱形的顶部
print(char * n)
# 循环用于打印菱形的中间部分
for i in range(n - 2):
# 打印左边的'*'
print(char, end='')
# 打印中间的空格
print(' ' * (n - 2), end='')
# 打印右边的'*'
print(char)
# 打印菱形的底部
print(char * n)
或者
# 设置菱形的大小为5行
n = 5
# 使用星号作为菱形的字符
char = '*'
# 循环遍历每一行
for i in range(n):
# 如果是第一行或最后一行
if i == 0 or i == n - 1:
# 打印n个星号,形成菱形的顶部和底部
print(char * n)
else:
# 打印一个星号,然后打印n-2个空格,再打印一个星号,形成菱形的中间部分
print(char + ' ' * (n - 2) + char)
另一种思路
取模,能整除n-1的就打印所有*
n = 5 # 设置菱形的大小
# 循环遍历每一行,这里直接使用了5次循环,也可以替换为使用变量n,即for i in range(n):
for i in range(5):
# 判断当前行号i是否是n-1的倍数(即第一行或最后一行)
if i % (n - 1) == 0:
# 如果是,则打印n个连续的'*',形成菱形的顶部和底部
print('*' * n)
else:
# 如果不是,则打印一个'*',接着打印n-2个空格,然后再打印一个'*',形成菱形的中间部分
print('*' + ' ' * (n - 2) + '*')
7、求100内所有奇数的和(2500)
# 初始化变量s为0,用于存储奇数和
s = 0
# 使用for循环遍历1到99之间的所有奇数,步长为2
# 即循环变量i的值依次为1, 3, 5, ..., 97, 99
for i in range(1, 100, 2):
# 将当前奇数i累加到变量s中
s += i
# 打印变量s的值,即1到99之间所有奇数的和
print(s)
建议使用sum内置函数,作用是求和
print(sum(range(1, 100, 2)))
8、成绩问题
判断学生成绩,成绩等级A至E。其中,90分以上为'A',8089分为'B',7079分为'C',60~69分为'D',60分以下为'E'
# 定义一个分数
score = 88
# 判断分数是否大于等于90
if score >= 90:
# 如果分数大于等于90,打印等级'A'
print('A')
# 判断分数是否大于等于80且小于90
elif score >= 80:
# 如果分数在80到90之间(不包括90),打印等级'B'
print('B')
# 判断分数是否大于等于70且小于80
elif score >= 70:
# 如果分数在70到80之间(不包括80),打印等级'C'
print('C')
# 判断分数是否大于等于60且小于70
elif score >= 60:
# 如果分数在60到70之间(不包括70),打印等级'D'
print('D')
else:
# 如果分数小于60,打印等级'E'
print('E')
9、求1到5阶乘之和
方法一
# 初始化n为5,代表我们要计算从1到5的每个数的阶乘的和
n = 5
# 初始化s为0,用于存储阶乘的和
s = 0
# 外层循环遍历从1到n的每个数
for i in range(1, n + 1):
# 初始化临时变量tmp为1,用于存储当前数的阶乘
tmp = 1
# 内层循环从2遍历到当前数i,计算阶乘
for j in range(2, i + 1):
# 将j乘到tmp上,逐步计算阶乘
tmp *= j
# 将计算出的阶乘加到s上
s += tmp
# 打印当前数的阶乘
print(tmp)
# 打印最终的阶乘和
print(s)
方法二
# 设置n为5,表示我们要计算从1到5的数的阶乘的和
n = 5
# 初始化s为0,用于存储阶乘的和
s = 0
# 初始化tmp为1,用于存储阶乘的临时结果
tmp = 1
# 循环遍历从1到n的每个数
for i in range(1, n + 1):
# 将tmp乘以当前数i,计算阶乘
tmp *= i
# 将计算得到的阶乘累加到s中
s += tmp
# 打印最终的阶乘和s
print(s)
10、给一个数,判断它是否是素数(质数)
质数:一个大于1的自然数只能被1和它本身整除
方法1
最简单的思路,按照定义来,假设有一个数n(n>1),从2开始判断,一直判断到n-1。
# 设置n为12577,这个数避开了3、5、10、2的倍数,因此可能是一个质数
n = 12577
# 初始化标志flag为False,我们假定n不是合数,如果n能被某个数整除,则标志置为True
flag = False
# 开始测试从2到n-1的所有数是否能整除n
for i in range(2, n):
# 如果n能被i整除,说明n是一个合数,将标志flag置为True,并结束循环
if n % i == 0:
flag = True
break
# 根据标志flag的值判断n是质数还是合数,并打印结果
if flag:
print(n, 'is a composite number') # 如果flag为True,则n是合数
else:
print(n, 'is a prime number') # 如果flag为False,则n是质数
与2取模,就可以直接判断它是否是一个偶数。
使用else子句
# 设置n为12577,该数字特意避开了3、5、10、2的倍数,以用于示例
n = 12577
# 通过一个循环从2遍历到n-1来检查n是否为质数
for i in range(2, n):
# 如果n能被i整除,说明n是一个合数
if n % i == 0:
# 输出结果并说明n是一个合数
print(n, 'is a composite number')
# 结束循环,因为我们已经确定n是一个合数
break
else:
# 如果循环完毕都没有找到能整除n的数,说明n是一个质数
print(n, 'is a prime number')
11、打印九九乘法表
思路:
1、使用for循环
# 外层循环,控制行数,从1循环到9(包括9)
for a in range(1, 10):
# 内层循环,控制列数,从1循环到当前行数a(包括a)
for b in range(1, a + 1):
# 使用format函数格式化字符串,打印出b*a=b*a的乘法表达式
print('{0}*{1}={2}'.format(b, a, b * a), end='\t')
# 打印完一行后,换行
print()
输出
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
分析:
- range作用:range(1,10)表示从1到10,range(1,a+1)表示从1到a+1
- format()函数:用来收集其后的位置参数和关键字段参数,并用他们的值填充字符串中的占位符,
'{0}*{1}={2}'.format(b,a,b*a)
意思是将b填充到{0},a填充到{1},b*a填充到{2},{0}*{1}={2}
也可写为{}*{}={}
- end='\t':表示换行
扩展
1*1=1 2*1=2 3*1=3 4*1=4 5*1=5 6*1=6 7*1=7 8*1=8 9*1=9
2*2=4 3*2=6 4*2=8 5*2=10 6*2=12 7*2=14 8*2=16 9*2=18
3*3=9 4*3=12 5*3=15 6*3=18 7*3=21 8*3=24 9*3=27
4*4=16 5*4=20 6*4=24 7*4=28 8*4=32 9*4=36
5*5=25 6*5=30 7*5=35 8*5=40 9*5=45
6*6=36 7*6=42 8*6=48 9*6=54
7*7=49 8*7=56 9*7=63
8*8=64 9*8=72
9*9=81
解答:
# 外层循环,控制行数,从1循环到9(包括9)
for a in range(1, 10):
# 打印前置的制表符,用于对齐乘法表。部分控制台可能需要更多的制表符来正确对齐,如print('\t' * 2 * (a - 1), end='')
print('\t' * (a - 1), end='')
# 内层循环,控制列数,从a循环到9(包括9),因此开始为a-0即a
for b in range(a - 0, 10):
# 使用format函数格式化字符串,打印出b*a的乘法表达式
print('{0}*{1}={2}'.format(b, a, b * a), end='\t')
# 打印完一行后,换行
print()
2、使用while嵌套
# 初始化行数为1
row = 1
# 当行数小于等于9时进入循环
while row <= 9:
# 对于每一行,初始化列数为1
column = 1
# 当列数小于等于行数时进入循环
while column <= row:
# 打印乘法公式,例如:1*1=1,1*2=2,2*2=4等
print('{}*{}={}'.format(column, row, row * column), end='\t')
# 完成一次打印后,列数加1,准备打印下一个乘法公式
column += 1
# 当一行打印完成后,换行
print()
# 准备打印下一行,行数加1
row += 1
分析:
- while嵌套会在使row没有等于9时不断重复运行代码
- row += 1 和column += 1意思是使变量在代码运行结束时+1
3、列表表达式
L = '\n'.join(
['\t'.join(['{}*{}={}'.format(column, row, row * column) for column in range(1, row + 1)]) for row in range(1, 10)])
print(L)
# 说明
# 初始化一个空字符串L,用来存储九九乘法表的结果
L = ''
# 通过外层循环遍历行,从1到9
for row in range(1, 10):
# 内层循环遍历列,从1到当前行号
for column in range(1, row + 1):
# 使用format格式化字符串,生成乘法公式,并添加到L中
L += '{}*{}={}\t'.format(column, row, row * column)
# 每完成一行的乘法公式后,换行
L += '\n'
# 打印九九乘法表的结果
print(L)
12、用户登录验证
- 用户依次输入用户名和密码,然后提交验证
- 用户不存在、密码错误,都显示用户名或密码错误提示
- 错误3次,则退出程序
- 验证成功则显示登录信息
# 设置用户名和密码
username = 'tom'
password = 'tom'
# 初始化登录成功标志为False
flag = False
# 循环三次尝试登录
for i in range(3):
# 获取用户输入的用户名
u = input('请输入用户名:')
# 获取用户输入的密码
p = input('请输入密码:')
# 检查用户名和密码是否正确
if username == u and password == p:
# 如果正确,设置登录成功标志为True,并退出循环
flag = True # 成功直接break
break
else:
# 如果不正确,打印错误提示,并给用户两次机会重新输入
print('用户名或密码错误,您还有', 2-i, '次尝试机会。')
# 根据登录成功标志,打印相应的提示信息
if not flag:
print('登录失败次数过多,账户已被锁定。')
else:
print('登录成功!')
13、打印下图菱形
*
***
*****
*******
*****
***
*
分析
行号 | 星个数 | 前空格数 | 总空格数 |
---|---|---|---|
1 | 1 | 3 | 6 |
2 | 3 | 2 | 4 |
3 | 5 | 1 | 2 |
4 | 7 | 0 | 0 |
5 | 5 | 1 | 2 |
6 | 3 | 2 | 4 |
7 | 1 | 3 | 6 |
方法一:
n = 7
height = n // 2 # 菱形上半部分的高度
fill_char = '*'
# 循环遍历菱形的每一行
for i in range(-height, n - height):
# 打印每一行,使用居中格式化
print("{:^{}}".format((n - 2 * abs(i)) * fill_char, n))
方法二:
# 遍历从-3到3的范围,包括-3和3
for i in range(-3, 4):
# 根据i的值计算空格的数量。如果i是负数,空格数量为-i,否则为i
spaces = -i if i < 0 else i
# 使用格式化字符串来创建并打印每一行。每一行包含'spaces'数量的空格,以及7-2*spaces数量的星号
print(f' {" " * spaces} * {(7 - 2 * spaces)} ')
方法三:
# 循环从-3到3,包括-3和3(总共7次迭代)
for i in range(-3, 4):
# 计算空格的数量,使用绝对值函数确保空格数为非负数
spaces = abs(i)
# 计算星号的数量,公式是7减去两倍的空格数,这样可以保证每一行的字符总数为7
stars = 7 - 2 * spaces
# 使用格式化字符串将空格和星号组合成一行
# f-string可以让我们直接把变量嵌入到字符串中,提高代码的可读性
line = f' {" " * spaces} {"*" * stars}'
# 打印这一行
print(line)
居中打印
# 循环从-3到3,总共会执行7次
for i in range(-3, 4):
# 计算当前行需要的星号数量。7减去两倍的i的绝对值,确保总数为7
stars_count = 7 - 2 * abs(i)
# 使用字符串格式化来居中显示星号。"{:^7}"表示宽度为7并居中对齐
# 通过format方法,将计算得到的星号数量转为对应的星号字符串
line = "{:^7}".format('*' * stars_count)
# 打印该行的内容
print(line)
1、打印对顶三角形
*******
*****
***
*
***
*****
*******
分析
序号 | 对称序列 | 星号数 | 总空格 | 前置空格 | 后置空格 |
---|---|---|---|---|---|
1 | 3 | 7 | 0 | 0 | 0 |
2 | 2 | 5 | 2 | 1 | 1 |
3 | 1 | 3 | 4 | 2 | 2 |
4 | 0 | 1 | 6 | 3 | 3 |
5 | 1 | 3 | 4 | 2 | 2 |
6 | 2 | 5 | 2 | 1 | 1 |
7 | 3 | 7 | 0 | 0 | 0 |
方法一
n = 7
# 计算菱形上半部分的高度,由于菱形的宽度为n,所以高度为n//2
e = n // 2
# 循环遍历菱形的每一行
# range的参数从-e到e,包括了菱形上半部分和下半部分的所有行
for i in range(-e, e + 1):
# 计算当前行左侧的空格数。空格数为e减去当前行的绝对值
spaces = e - abs(i)
# 计算当前行的星号数。星号数为2乘以当前行的绝对值再加1
stars = 2 * abs(i) + 1
# 打印当前行,由spaces个空格和stars个星号组成
print(spaces * ' ' + stars * '*')
方法二
# 设置菱形的最大宽度为7
n = 7
# 循环从-3到3,这是基于n//2的结果,这样确保了菱形的高度和宽度相适应
for i in range(-3, 4):
# 计算当前行需要的星号数量。2 * abs(i) + 1 是根据菱形的形状来确定的
stars_count = 2 * abs(i) + 1
# 生成由星号组成的字符串。例如,如果stars_count为3,那么结果就是'***'
star_string = '*' * stars_count
# 使用字符串格式化来居中显示星号字符串。"{:^7}"表示宽度为7并居中对齐
print("{:^7}".format(star_string))
# 如果不想使用上面的方式来生成星号字符串,也可以使用下面这行代码来代替print语句
# line = (2 * abs(i) + 1) * '*'
# print("{:^{}}".format(line, n))
2、打印闪电
*
**
***
*******
***
**
*
分析
行号 | *个数 | 前空格数 | 后空格数 | 总空格数 | 数据 |
---|---|---|---|---|---|
1 | 1 | 3 | 3 | 6 | -3 |
2 | 2 | 2 | 3 | 5 | -2 |
3 | 3 | 1 | 3 | 4 | -1 |
4 | 7 | 0 | 0 | 0 | 0 |
5 | 3 | 3 | 1 | 4 | 1 |
6 | 2 | 3 | 2 | 5 | 2 |
7 | 1 | 3 | 3 | 6 | 3 |
方法一
# 遍历从-3到3的范围
for i in range(-3, 4):
# 如果i小于0(即-3到-1),打印宽度为-i的空格和宽度为4+i的星号
if i < 0:
print(' ' * (-i) + '*' * (4 + i))
# 如果i大于0(即1到3),打印宽度为3的空格和宽度为4-i的星号
elif i > 0:
print(' ' * 3 + '*' * (4 - i))
# 如果i等于0,即菱形的中间行,打印宽度为7的星号
else:
print('*' * 7)
方法二
# 设置菱形的最大宽度为 7
n = 7
# 计算菱形上半部分的高度,因为菱形是对称的,所以高度是最大宽度的一半
e = n // 2
# 计算菱形下半部分的高度(包括中间行),f 为 e+1,因为下半部分比上半部分多一行
f = e + 1
# 循环遍历菱形的每一行,i 的范围是从 -e 到 f(不包括 f)
for i in range(-e, f):
# 如果 i 小于 0,表示在菱形的上半部分
if i < 0:
# 打印当前行,前面是 -i 个空格,后面是 (f + i) 个星号
print(' ' * -i + (f + i) * '*')
# 如果 i 大于 0,表示在菱形的下半部分(不包括中间行)
elif i > 0:
# 打印当前行,前面是 e 个空格,后面是 (f - i) 个星号
print(' ' * e + (f - i) * '*')
# 如果 i 等于 0,表示在菱形的中间行
else: # 这个 else 条件可以简写为 `elif i == 0:`,但为了清晰明确,我们保持这样写也没有问题
# 打印中间行,这一行全是星号,数量为 n
print(n * '*')
14、打印100以内的斐波那契数列
斐波那契数列指的是这样一个数列:
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711……
如果设F(n)为该数列的第n项(n∈N*),那么这句话可以写成如下形式::F(n)=F(n-1)+F(n-2)F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2),这是一个线性递推数列
它的规律是:这个数列从第 3 项开始,每一项都等于前两项之和。
思路
1、for循环
# 初始化变量 i 和 j,它们是斐波那契数列的前两个数字
i = 1
j = 0
# 创建一个范围从0到100的循环,用于生成斐波那契数列
for a in range(101):
# 计算斐波那契数列的下一个数字,即前两个数字的和
number = i + j
# 在进入下一次循环之前,更新i和j的值
i = j
j = number
# 如果生成的斐波那契数字超过100,就退出循环
if number > 100:
break
else: # 否则,打印生成的斐波那契数字
print(number)
2、while循环
# 初始化斐波那契数列的前两个数字
a = 0
b = 1
# 打印斐波那契数列的第一个数字
print(a)
# 使用无限循环开始生成斐波那契数列
while True:
# 打印斐波那契数列的第二个及以后的数字
print(b)
# 计算下一个斐波那契数
c = a + b
# 如果生成的斐波那契数超过100,则跳出循环
if c > 100: break
# 更新斐波那契数列的前两个数字,以备下一次循环使用
a = b
b = c
15、求斐波那契数列第101项
方法一
# 初始化斐波那契数列的前两个数字,第一个数为1,第二个数为0
a = 1
b = 0
# 打印第一个数(即索引为0的数)
print('index={},fib={}'.format(0, b))
# 打印第二个数(即索引为1的数)
print('index={},fib={}'.format(1, a))
# 初始化索引为2,用于记录当前生成的数的位置
index = 2
# 使用无限循环开始生成并打印斐波那契数列
while True:
# 计算下一个斐波那契数,即前两个数的和
c = a + b
# 更新索引值
index += 1
# 打印当前生成的斐波那契数及其索引位置
print('index={},fib={}'.format(index, c))
# 如果生成的数的索引达到102,则跳出循环。注意:这里用102是为了打印到索引为101的数
if index == 102: break
# 更新斐波那契数列的下一个两个数,以备下一次循环使用
a = b
b = c
方法二
# 初始化斐波那契数列的前两个数字,都为1
a = 1
b = 1
# 通过for循环来计算斐波那契数列
# 注意这里循环了101次,所以计算的是第101个斐波那契数
for count in range(101):
# 这一行是斐波那契数列的核心计算逻辑
# 它实现了这样的计算: b = a + b, a = b
# 即在下一次循环中,a和b会分别变为前一次循环中的b和a+b
a, b = b, a + b
# for-else结构中的else部分会在for循环正常结束后执行
# 这里就是在循环结束后打印出第100个斐波那契数
else:
print(b)
方法三
# 初始化斐波那契数列的前两个数
a = 1
b = 1
# 循环从第三个数开始计算到第102个数
for i in range(2, 102):
# 如果当前是第101个数
if i == 101:
# 打印第101个斐波那契数
print(b)
else:
# 计算下一个斐波那契数,并更新a和b的值
a, b = b, a + b
16、求10万内的所有素数
方法一
# 设置要查找素数的上限
num = 100000
# 初始化一个空字符串,用于存储所有的素数
strs = ''
# 遍历2到num-1的所有数字
for i in range(2, num):
# 遍历2到i的平方根的所有数字,检查是否有能整除i的因子
for c in range(2, int(i ** 0.5) + 1):
if i % c == 0:
# 如果找到了能整除i的因子,则跳出内部循环,继续下一个数字的检查
break
else:
# 如果没有找到能整除i的因子,说明i是一个素数,将其添加到字符串中
strs += str(i) + ' '
# 打印所有的素数
print(strs)
方法二
# 初始化计数器,用于统计找到的素数数量
count = 0
# 外层循环从2遍历到99999,检查每一个数字是否为素数
for a in range(2, 100000):
# 内层循环从2遍历到a的平方根,试图找到a的因子
for b in range(2, int(a ** 0.5) + 1):
# 如果找到了a的一个因子(即a能被b整除),则跳出内层循环
if a % b == 0:
break
else:
# 如果内层循环完成,没有找到a的因子,那么a就是一个素数
# 打印出这个素数,并且计数器加1
print(a)
count += 1
# 打印出找到的素数数量
print("Total prime numbers found:", count)
方法三
# 初始化计数器为1,因为我们已经知道2是素数,所以从3开始计数
count = 1
# 从3开始,以步长为2遍历到99999,这样只检查奇数
for a in range(3, 100000, 2):
# 假设a是素数,我们将在内部循环中检查这个假设
is_prime = True
# 从3开始,以步长为2遍历到a的平方根,只检查奇数可能的因子
for b in range(3, int(a ** 0.5) + 1, 2):
# 如果a能被b整除,那么a不是素数
if a % b == 0:
is_prime = False
break
# 如果a是素数,打印它的值
if is_prime:
print(a)
count += 1
# 打印出找到的素数数量
print("Total odd prime numbers found:", count)
查看程序运行时间
import datetime
start = datetime.datetime.now()
# 程序
delta = (datetime.datetime.now() - start).total_seconds() # 它不是精确的CPU,它是墙上的时间
print(count, delta)
17、求100内的素数
- 从2开始到自身的数-1中找到一个能整除的=>从2开始到自身开平方的数中找到一个能整除的
- 一个合数一定可以分解成几个素数的乘积,也就是说,一个数如果能被一个素数整除就是合数
方法一
import datetime
# 获取当前时间,用于后续计算程序运行时间
start = datetime.datetime.now()
# 设置一个上限,用于遍历所有的数字
n = 100000
# 2和3都是质数,所以初始化质数的数量为2
count = 2
# 从3开始遍历所有的奇数,步长为2(只考虑奇数,因为偶数除了2以外不可能是质数)
for x in range(3, n, 2):
# 假设x是质数
is_prime = True
# 遍历所有奇数因子,步长为2,只考虑到x的平方根即可(如果x不是质数,那么它必然有一个因子不大于它的平方根)
for i in range(3, int(x ** 0.5) + 1, 2):
# 如果x能被i整除,说明x不是质数
if x % i == 0:
# x不是质数,标记并结束内层循环
is_prime = False
break
# 如果内层循环结束后,x仍然是质数,则质数计数器+1
if is_prime:
count += 1
# 计算程序运行时间
delta = (datetime.datetime.now() - start).total_seconds()
# 打印找到的质数的数量和程序运行的时间
print("Total prime numbers found:", count)
print("Program run time in seconds:", delta)
方法二
import datetime
start = datetime.datetime.now() # 记录开始时间
n = 100000 # 设置搜索上限
count = 2 # 初始化质数计数器为2,因为2和3是前两个质数
primenumbers = [3] # 初始化质数列表,从3开始(为什么是3?因为2是唯一的偶数质数,而我们的循环从5开始,只考虑奇数,所以从3开始)
# 循环遍历从5开始的奇数
for x in range(5, n, 2): # 从5开始,步长为2,舍弃掉所有偶数,因为除了2以外,偶数都不是质数
edge = int(x ** 0.5) # 计算x的平方根并向下取整,用作判断x是否为质数的一个界限
flag = False # 初始化标志位为False,表示x目前未被认定为质数
# 遍历质数列表中的每一个质数
for i in primenumbers:
if i > edge: # 如果当前质数i大于界限edge,说明x是质数
flag = True # 设置标志位为True
break # 退出循环,因为已经确定x是质数
if x % i == 0: # 如果x能被当前质数i整除,说明x不是质数,而是合数
break # 退出循环,因为已经确定x不是质数
if flag: # 如果标志位为True,说明x是质数
count += 1 # 质数计数器加1
primenumbers.append(x) # 将新的质数x添加到质数列表中
delta = (datetime.datetime.now() - start).total_seconds() # 计算程序运行时间
print(count, delta) # 打印找到的质数的数量和程序运行时间
经过测试发现,上面的代码计算效率最高。算法中增加了列表,记录了质数,控制了边界后,使用质数来取模比使用奇数计算更少。空间换时间,使用列表空间存储质数列表,来换取计算时间。
1、孪生素数性质
大于3的素数只有6N-1和6N+1两种形式,如果6N-1和6N+1都是素数称为孪生素数
方法一
import datetime
# 记录程序开始时间
start = datetime.datetime.now()
# 设置需要检测的最大数字
n = 100000
# 从7开始检测,因为2,3,5已经被确定为质数
x = 7
# 设置步长,初始为4,用于在x的基础上递增得到下一个待检测的数字
step = 4
# 已知的质数列表,初始包含2,3,5三个质数
primenumbers = [3, 5]
# 记录找到的质数个数,初始为3,因为2,3,5是质数
count = 3
# 当x小于n时,进行循环检测
while x < n:
# 如果x不是5的倍数,才可能是质数,才需要进行下一步的检测
if x % 5 != 0:
# 计算x的平方根并向下取整,用于减少质数检测次数
edge = int(x ** 0.5)
# 标志位,用于标记x是否为质数,初始为False
flag = False
# 在已知的质数列表中进行检测
for i in primenumbers:
# 如果i大于edge,说明x是质数,因为x的所有可能因子都已经检测过
if i > edge:
flag = True # 标记x为质数
break # 跳出循环
# 如果x能被i整除,说明x是合数
if x % i == 0:
break # 跳出循环
# 如果x被标记为质数,则增加质数个数,并将x加入到质数列表中
if flag:
count += 1
primenumbers.append(x)
# 步长变换,如果是2就变为4,如果是4就变为2,这样可以跳过偶数(除了2以外的偶数不可能是质数)
x += step
step = 4 if step == 2 else 2
# 计算程序运行时间
delta = (datetime.datetime.now() - start).total_seconds()
# 打印找到的质数个数和程序运行时间
print(count, delta)
方法二
import datetime
start = datetime.datetime.now() # 记录程序开始时间
n = 100000
count = 2 # 从3开始,所以初始质数数量为2(2和3)
primenumbers = [2, 3] # 质数列表,从2开始
for x in range(5, n, 2): # 从5开始,步长为2,只测试大于2的奇数
if x % 5 == 0: # 如果x能被5整除,那就不是质数
continue # 跳过本次循环,进入下一次循环
edge = int(x ** 0.5) # 计算x的平方根并向下取整,用于减少需要检查的除数数量
flag = False # 标志位,假设x是质数
for i in primenumbers: # 遍历已知的质数列表
if i > edge: # 如果已知的质数i大于x的平方根,那么x不可能是合数,因为合数必定有一个因子小于等于其平方根
flag = True # 设置标志位为True,表示x是质数
break # 退出循环,不再检查其他的质数
if x % i == 0: # 如果x能被已知的质数i整除,那么x就是合数
break # 退出循环,不再检查其他的质数
if flag: # 如果标志位为True,表示x是质数
count += 1 # 质数计数器加1
primenumbers.append(x) # 将新的质数加入到质数列表中
delta = (datetime.datetime.now() - start).total_seconds() # 计算程序运行时间
print(count, delta) # 打印找到的质数数量和程序运行时间
18、计算杨辉三角前6行
- 第n行有n项,n是正整数52
- 第n行数字之和为2**(n-1)
- 打印出杨辉三角的每一行数字即可
解法一:逐行计算
# 初始化pre为Pascal三角形的第一行
pre = [1]
# 设置要生成的Pascal三角形的行数
n = 6
# 循环遍历每一行
for i in range(n):
# 初始化当前行cur,第一个元素总是1
cur = [1]
# 如果不是第一行(因为第一行只有一个元素,就是1)
if i != 0:
# 遍历前i-1个元素,因为它们可以通过前一行的相邻两个元素相加得到
for j in range(1, i):
# 当前元素是前一行的相邻两个元素之和
cur.append(pre[j - 1] + pre[j])
# 每行的最后一个元素总是1
cur.append(1)
# 打印当前行
print(cur)
# 将当前行设为下一行的前置行
pre = cur
解法一:补零
# 初始化pre为第一行[1],因为Pascal三角形的第一行只有一个元素1
pre = [1] # 第一行是特例,因为0+0不等于1
# n表示要生成的Pascal三角形的行数
n = 6
# 从第二行开始循环生成n-1行Pascal三角形(因为第一行已经初始化给pre了)
for i in range(1, n):
# 在循环内部开辟内存空间,初始化当前行为全0列表
cur = [0] * (i + 1) # 在循环内部开辟内存空间
# j循环控制当前行的索引
for j in range(i + 1):
# 如果j是0(即当前行的第一个元素)或j等于i(即当前行的最后一个元素)
if j == 0 or j == i:
# 当前行的第一个和最后一个元素设为1
cur[j] = 1
else:
# 当前行的元素等于前一行的相邻两个元素之和
cur[j] = pre[j - 1] + pre[j]
# 打印当前行
print(cur)
# 将当前行设为下一行的前一行
pre = cur
解法三:对称
- 杨辉三角中心对称
- 行索引为奇数,左右数字个数相同,只需计算左边所有数字
- 行索引为偶数,只需计算左边所有数字,最中心数字只需计算一次
- 为每一行直接开辟够空间,两端1不要计算了
n = 6 # n表示要生成的杨辉三角的行数
pre = [1] # pre存储前一行的值,初始化为[1]
# 循环生成n行Pascal三角形
for i in range(n):
cur = [1] * (i + 1) # cur存储当前行的值,每行初始化为1
# j的范围从1到i-1,因为每行的两端都是1,不需要计算
for j in range(1, i):
cur[j] = pre[j - 1] + pre[j] # 当前行的每个元素是前一行的相邻两个元素之和
print(cur) # 打印当前行
pre = cur # 将当前行设为下一行的前一行
19、依次接收用户输入的3个数,排序后打印
- 转换int后,判断大小排序。使用分支结构完成
- 使用max函数
- 使用列表的sort方法
- 冒泡法
sorted()
函数
假定默认升序输出
第一种方法
a = []
# while 循环
# while True:
# a.append(int(input('>>>')))
# if len(a) >= 3:
# break
# for 循环
for i in range(3): # range(1,4) 也可以
a.append(int(input('请输入数字:'))) # 将输入转换为整数
print(a)
if a[0] > a[1] > a[2]:
print(a[2], a[1], a[0])
elif a[0] > a[2] > a[1]:
print(a[1], a[2], a[0])
elif a[1] > a[0] > a[2]:
print(a[2], a[0], a[1])
elif a[1] > a[2] > a[0]:
print(a[0], a[2], a[1])
elif a[2] > a[0] > a[1]:
print(a[1], a[0], a[2])
else:
print(a[0], a[1], a[2])
第二种方法
# 初始化两个空列表a和b
a = []
b = []
# 从用户那里获取三个数字输入,并将它们添加到列表a中
for i in range(3):
a.append(int(input('请输入数字:'))) # 将用户输入转换为整数
print(a)
while a: # 当 a 为空列表
m = max(a) # 找到列表 a 中的最大值m
b.insert(0, m) # 将这个最大值m插入到列表b的开头
a.remove(m) # 从列表a中移除这个最大值m,直到列表a为空
print(b)
第三种方法
a = []
for i in range(3):
a.append(int(input('请输入数字:'))) # 将输入转换为整数
print(a)
a.sort() # 对这个列表进行排序
print(a)
第四种方法
冒泡排序(Bubble Sort)
是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
- 排序算法,一般都实现为就地排序,输出为升序
- 扩大有序区,减小无序区。
- 每一趟比较中,将无序区中所有元素依次两两比较,升序排序将大数调整到两数中的右侧
- 每一趟比较完成,都会把这一趟的最大数推倒当前无序区的最右侧
import random
# 使用random.sample()直接生成10个不重复的随机数
a = random.sample(range(1, 101), 10)
print("原始随机数组:", a)
# 使用冒泡排序对数组进行排序
for j in range(len(a)): # 这是外层循环,它的次数等于数组 a 的长度。每一次循环,都会将当前最大的数“冒泡”到它应该在的位置上
for k in range(len(a) - j - 1): # 这是内层循环。它遍历数组,与相邻的元素进行比较。由于每次外层循环后,最大的数都会冒泡到最后,所以内层循环每次可以减少一次比较
if a[k] > a[k + 1]: # 这个条件判断当前元素 a[k] 是否大于它的下一个元素 a[k + 1]。如果大于,那么它们的顺序是错误的,需要交换
a[k], a[k + 1] = a[k + 1], a[k] # 使用Python的元组交换法
print("使用冒泡排序后的数组:", a)
- 冒泡法需要数据一趟趟比较
- 可以设定一个标记判断此轮是否有数据交换发生,如果没有发生交换,可以结束排序,如果发生交换,继续下一轮排序
- 最差的排序情况是,初始顺序与目标顺序完全相反,遍历次数1,..,n-1之和n(n-1)/2
- 最好的排序情况是,初始顺序与目标顺序完全相同,遍历次数n-1
- 时间复杂度O(n^2)
第五种方法
import random
# 使用random.sample()直接生成10个不重复的随机数
a = random.sample(range(1, 101), 10)
print("原始随机数组:", a)
# 使用sorted()函数对数组进行排序
a = sorted(a)
print("排序后的数组:", a)
20、判断数字并打印
用户输入一个十进制正整数数字
1、判断是几位数
2、打印每一位数字及其重复的次数
3、依次打印每一位数字,顺序个、十、百、干、万...位
# 初始化一个空字符串
num = ''
# 通过循环判断输入,确保输入的是一个正整数
# 数字输入的简单判断
while True:
num = input('Input a positive number>>>').strip().lstrip('0')
if num.isdigit():
break
# 打印输入的数字以及其长度
print("The length of {} is {}.".format(num, len(num)))
# 倒序打印数字方法一:通过range函数倒序遍历索引
# 倒序打印1
for i in range(len(num), 0, -1):
print(num[i - 1], end='')
print()
# 倒序打印数字方法二:通过reversed函数倒序遍历字符
# 倒序打印2
for i in reversed(num):
print(i, end='')
print()
# 下面的倒序打印方法都是重复的,可以选择删除以提高代码简洁性
# 判断0-9每个数字在输入的数字中出现的次数
# 初始化一个长度为10的计数器列表
counter = [0] * 10
# 方法一:通过count函数计算每个数字的出现次数,此方法效率较低,每次count都是全字符串扫描
for i in range(10): # 10*n
counter[i] = num.count(str(i))
if any(counter): # 如果counter中有非0元素,打印计数结果
for i in range(10):
if counter[i]:
print("The count of {} is {}".format(i, counter[i]))
# 方法二:通过遍历每个字符,然后计数,此方法效率较高,只需一次遍历
counter = [0] * 10
for x in num: # 0(n)
counter[int(x)] += 1
if any(counter): # 如果counter中有非0元素,打印计数结果
for i in range(10):
if counter[i]:
print("The count of {} is {}".format(i, counter[i]))
21、判断数字位数并排序打印
输入5个十进制正整数数字,判断输入的这些数字分别是几位数,将这些数字排序打印,要求升序打印
# 创建一个空列表用于存储用户输入的数字
nums = []
# 循环直到列表中有5个数字
while len(nums) < 5:
# 获取用户输入,去掉前后的空白,并去掉前导0
num = input("Please input a number:").strip().lstrip('0')
# 判断用户输入的是否为数字,如果不是则重新获取输入
if not num.isdigit():
continue
# 打印输入的数字及其长度
print('The length of {} is {}'.format(num, len(num)))
# 将数字添加到列表中,这里将字符串转换为整数
nums.append(int(num))
# 打印最后得到的数字列表
print(nums)
# 创建一个数字的副本,用于排序
lst = nums.copy()
# 使用sort()方法对列表进行排序,这将直接修改原列表
lst.sort() # 就地修改
print(lst)
# 使用冒泡排序对原数字列表进行排序
for i in range(len(nums)):
flag = False
for j in range(len(nums) - i - 1):
# 如果当前数字大于下一个数字,则交换它们的位置
if nums[j] > nums[j + 1]:
tmp = nums[j]
nums[j] = nums[j + 1]
nums[j + 1] = tmp
flag = True
# 如果在某次循环中没有发生任何交换,那么列表已经排序完成,可以提前退出循环
if not flag:
break
# 打印排序后的数字列表
print(nums)
22、解决猴子吃桃问题
猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想吃时,只剩下一个桃子了。求第一天共摘多少个桃子?
peach = 1
for i in range(9):
peach = 2 * (peach + 1)
print(peach) # 1534
23、求杨辉三角第n行第k列的值
算法一
一次开辟本次列表需要的内存空间,提高效率
只保留2个列表,减少空间使用
# 初始化变量m,表示我们要生成的斐波那契数列的长度
m = 9
# 初始化变量k,表示我们要获取的斐波那契数列的索引(从1开始)
k = 5
# 初始化变量pre,它是一个列表,用来存储生成的斐波那契数列。初始化为None,因为还没有生成任何数。
pre = None
# 开始一个外循环,用来生成斐波那契数列的每一行。我们将生成m行,每行有i+1个元素。
for i in range(m):
# 创建一个新的列表row,用来存储当前正在生成的行。这个列表的长度是i+1,因为我们要生成i+1个元素。
row = [1] * (i + 1)
# 开始一个内循环,用来计算这一行的除了第一个元素之外的其他元素。这些元素都是前两个元素的和。
for j in range(1, i):
# 计算当前元素的值,它等于前一个元素和前两个元素的和。
row[j] = pre[j - 1] + pre[j]
# 在计算完这一行的所有元素后,将这个行赋值给pre,以便在下一个迭代中生成下一行。
pre = row
# 打印一个分隔线,以便在输出中更清楚地看到每一行。
print('---------')
# 打印最后一行,也就是我们生成的斐波那契数列。由于我们是从0开始索引的,所以第k个元素实际上是这一行的第k-1个元素。
print(row) # [1, 8, 28, 56, 70, 56, 28, 8, 1]
# 打印第k个元素的值。注意这里我们使用的是k-1作为索引,因为Python的列表索引是从0开始的。
print(row[k - 1]) # 70
也可以使用对称,减少迭代次数和计算次数。
算法二
根据杨辉三角的定理:第n行的m个数(m>0且n>0)可表示为C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数。
组合数公式:有m个不同元素,任意取n(n≤m)个元素,记作c(m,n),组合数公式为:
C(m,n)=m!/(n!(m-n)!)
C(m,n)=C(m,m-n)
# 第n行的m个数可表示为C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数
m = 9 # 定义m为9
k = 5 # 定义k为5
# C(m-1,k-1),还可等价为C(m-1,m-1-(k-1))=>C(m-1,m-k)
# 计算组合数C(m-1,k-1),它与C(m-1,m-k)是等价的
# C(n,r)=n!/(r!(n-r)!)
n = m - 1 # n等于m减1
r = k - 1 # r等于k减1
d = n - r # 计算n-r的值,存储在d中
targets = [] # 创建一个空列表用于存储目标值
# 目标值为 r , n-r , n
factorial = 1 # 初始化阶乘值为1
# 可以加入k为1或者m的判断,直接返回1
# 通过循环计算阶乘,当i等于r、d或n时,将阶乘值添加到targets列表中
for i in range(1, n + 1):
factorial *= i # 计算i的阶乘
if i == r: # 如果i等于r
targets.append(factorial) # 将阶乘值添加到目标列表中
if i == d: # 如果i等于d
targets.append(factorial) # 将阶乘值添加到目标列表中
if i == n: # 如果i等于n
targets.append(factorial) # 将阶乘值添加到目标列表中
print(targets) # 打印目标列表
print(targets[2] // (targets[0] * targets[1])) # 打印最终结果,即C(n,r)的值
i==r、i==n、i==d这三个条件不要写在一起,因为它们有可能两两相等。
算法说明:一趟到n的阶乘算出所有阶乘值。
24、数字统计
随机产生10个数字
要求:
- 每个数字取值范围[1,20]
- 统计重复的数字有几个?分别是什么?
- 统计不重复的数字有几个?分别是什么?
- 举例:11,7,5,11,6,7,4,其中2个数字7和11重复了,3个数字4、5、6没有重复过
思路:
对于一个排序的序列,相等的数字会挨在一起。但是如果先排序,还是要花时间,能否不排序解决?例如11,7,5,11,6,7,4,先拿出11,依次从第二个数字开始比较,发现11就把对应索引标记,这样一趟比较就知道11是否重复,哪些地方重复。第二趟使用7和其后数字依次比较,发现7就标记,当遇到以前比较过的11的位置的时候,其索引已经被标记为1,直接跳过。
# 导入random模块,用于生成随机数
import random
# 创建一个空列表nums,用于存储随机生成的数字
nums = []
# 在循环中生成10个随机数并添加到nums中
for _ in range(10):
# random.randrange(21)生成一个0到20之间的随机整数,包括0和20
nums.append(random.randrange(21))
# 这行代码注释掉了nums的输出,如果需要查看生成的随机数,可以去掉注释
# nums=[2,10,19,20,4,17,4,20,11,3]
print("Origin numbers = {}".format(nums))
print()
# 获取nums的长度
length = len(nums)
# 创建一个空列表samenums,用于存储重复的数字
samenums = []
# 创建一个空列表diffnums,用于存储不重复的数字
diffnums = []
# 创建一个长度为length的列表states,用于记录每个数字是否已经出现过,0表示未出现,1表示已出现
states = [0] * length
# 遍历每个数字
for i in range(length):
# 假定当前数字没有重复
flag = False
# 如果当前数字已经出现过,则跳过该数字的后续比较,因为已经确定它是重复的
if states[i] == 1:
continue
# 从i+1开始寻找与当前数字相同的数字,因为i之前的数字已经被考虑过了
for j in range(i + 1, length):
# 如果j位置的数字已经出现过,则跳过该数字的比较,因为已经确定它是重复的
if states[j] == 1:
continue
# 如果找到了与当前数字相同的数字,则设置flag为True,并把j位置的数字标记为已出现,以便后续不再考虑它
if nums[i] == nums[j]:
flag = True
states[j] = 1
# 根据flag的值,判断当前数字是否重复,如果重复,则把该数字添加到samenums中,并把该数字标记为已出现;否则,把该数字添加到diffnums中。
if flag:
samenums.append(nums[i])
states[i] = 1
else:
diffnums.append(nums[i])
print("Same numbers ={1}, Counter ={0}".format(len(samenums), samenums))
print("Different numbers ={1}, Counter ={0}".format(len(diffnums), diffnums))
想知道某个数字重复的次数
# 导入random模块,用于生成随机数
import random
# 创建一个空列表nums,用于存储随机生成的数字
nums = []
# 生成10个随机数并添加到nums中
for _ in range(10):
nums.append(random.randrange(21))
# 手动设置nums的值
nums = [1, 22, 33, 56, 56, 22, 4, 56, 9, 56, 2, 1]
print("Origin numbers = {}".format(nums))
print()
# 获取nums的长度
length = len(nums)
# 创建一个空列表samenums,用于存储重复的数字,每个元素是一个元组,元组的第一个元素是重复的数字,第二个元素是该数字出现的次数
samenums = []
# 创建一个空列表diffnums,用于存储不重复的数字
diffnums = []
# 创建一个长度为length的列表states,用于记录每个数字是否已经出现过,0表示未出现,非0表示已出现次数(数字本身)
states = [0] * length # 记录不同的索引异同状态
# 遍历每个数字
for i in range(length):
# 如果当前数字已经出现过,则跳过该数字的后续比较,因为已经确定它是重复的
if states[i] != 0:
continue
# count用于记录当前数字出现的次数,初始值为0
count = 0 # 假定没有重复
# 从i+1开始寻找与当前数字相同的数字,因为i之前的数字已经被考虑过了
for j in range(i + 1, length):
# 如果j位置的数字已经出现过,则跳过该数字的比较,因为已经确定它是重复的
if states[j] != 0:
continue
# 如果找到了与当前数字相同的数字,则把count加1,并把j位置的数字标记为已出现,以便后续不再考虑它
if nums[i] == nums[j]:
count += 1
states[j] = count
# 如果count不为0,说明存在重复的数字,把states[i]的值设置为count+1,并把元组(nums[i], states[i])添加到samenums中;否则,把nums[i]添加到diffnums中。
if count: # 有重复
states[i] = count + 1
samenums.append((nums[i], states[i]))
else:
diffnums.append(nums[i])
print("Same numbers={1}, Counter={0}".format(len(samenums), samenums)) # 打印重复数字的数量和列表
print("Different numbers={1}, Counter={0}".format(len(diffnums), diffnums)) # 打印不同数字的数量和列表
print(states) # 打印每个数字的出现次数状态列表
25、集合
- 共同好友
- 你的好友A、B、C,他的好友C、B、D,求共同好友
# 定义了一个名为yours的集合,包含元素'B', 'C', 'A'
yours = {'B', 'C', 'A'}
# 定义了一个名为his的集合,包含元素'B', 'C', 'D'
his = {'B', 'C', 'D'}
# 使用&运算符找到yours和his的交集,并将结果赋值给变量intersection
intersection = yours & his
# 打印intersection集合,即yours和his的交集
print(intersection)
- 微信群提醒
- XXX与群里其他人都不是微信朋友关系
已知微信群里有a、b、c三个人,加入了x,x和其他人都不是好友
-
并集处理
-
x-userid not in(A|B|C|..)==True,X用户的ID并不在该群当前所有成员的好友并集,说明它不是任何人的朋友。这种方式会产生巨大的并集
-
假设x用户的好友列表是T,该群所有用户的id集合为IDs,IDs&T==set()
-
# 定义三个集合,分别表示群里三个用户的微信朋友关系
A = {"userid1", "userid2", "userid3"}
B = {"userid4", "userid5", "userid6"}
C = {"userid7", "userid8", "userid9"}
# 新加入的用户x的微信用户ID
x_userid = "userid10"
# 检查x_userid是否在A、B或C中的任意一个中
x_userid in A or x_userid in B or x_userid in C
# 检查x_userid是否在A、B或C集合中
x_userid in (A | B | C)
# 或者合并三个集合
IDs = A | B | C
# 检查x_userid是否与集合IDs有交集,如果有交集,则返回True,否则返回False
IDs & x_userid != set()
# 检查删除x_userid后,IDs是否仍然是IDs的子集。如果是,则返回True,否则返回False
IDs - x_userid < IDs
# 使用isdisjoint方法检查x_userid是否与IDs完全独立,即没有任何交集。如果存在交集,则返回False,否则返回True
IDs.isdisjoint(x_userid) == False
-
有一个API,要求权限同时具备A、B、C才能访问,用户权限是B、C、D,判断用户是否能够访问该API
-
假设API权限为集合T,用户权限为集合P
-
T&P==T
-
T<=P即T是P的子集
-
T-P==set()差集为空说明P完全包含T
-
-
T = {A, B, C}
P = {B, C, D}
# 判断T中的所有元素是否都在P中存在,如果都在,那么T就是P的子集,用户可以访问这个API
T - P == set()
# 判断T和P的交集是否等于T。如果等于,说明用户拥有的权限能够满足API的要求,可以访问这个API
T & P == T
# 判断T是否是P的子集。如果是,说明用户的权限集合P包含了API所需的所有权限,用户可以访问这个API
T <= P
# 使用issubset方法判断P是否是T的子集, 这个方法用于检查一个集合(set)是否包含另一个集合(set)中的所有元素的函数
T.issubset(P)
- 有一个API,要求权限具备A、B、C任意一项就可访问,用户权限是B、C、D,判断用户是否能够访问该API
T = {A, B, C}
P = {B, C, D}
# 判断T和P的交集是否不等于空集。如果不等于空集,说明用户拥有的权限能够满足API的要求,可以访问这个API
T & P !== set()
# 判断T中不包含P的元素是否还是T的子集。如果是,说明用户的权限集合P包含了API所需的所有权限,用户可以访问这个API
T - P < T
# isdisjoint方法是判断两个集合是否互不交叠,即没有任何交集。如果isdisjoint返回False,说明两个集合有交集
T.isdisjoint(P) == False
-
一个总任务列表,存储所有任务。一个已完成的任务列表。找出为未完成的任务
-
任务ID不重复
-
所有任务ID集合放到集合ALL中
-
所有已经完成的任务ID都放到集合COMPLETED中,它一定是ALL的子集
-
ALL-COMPLETED=>UNCOMPLETED
-
列表运算
# 总任务列表,包含所有任务
ALL = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print("总任务列表:", ALL)
# 已完成任务列表,包含已完成任务的ID
COMPLETED = [2, 4, 6, 8, 10]
print("已完成任务列表:", COMPLETED)
# 定义一个空列表,用于存储未完成的任务ID
UNCOMPLETED = []
# 遍历总任务列表中的每一个任务ID
for id in ALL:
# 检查当前的任务ID是否在已完成任务列表中
if id not in COMPLETED:
# 如果当前任务ID不在已完成任务列表中,就把它添加到UNCOMPLETED列表中
UNCOMPLETED.append(id)
print("未完成任务列表:", UNCOMPLETED)
或者集合运算(推荐)
# 定义一个总任务列表,存储所有的任务,这里使用数字1到10作为示例任务
ALL = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
# 打印总任务列表,用于核对和确认总任务列表的内容
print(ALL)
# 定义一个已完成的任务列表,这里使用数字2, 4, 6, 8, 10作为已完成的任务示例
COMPLETED = {2, 4, 6, 8, 10}
# 使用集合操作“-”从总任务列表中移除已完成的任务,得到未完成的任务列表
# 这是一种快捷的方法来找到两个列表的差集
UNCOMPLETED = ALL - COMPLETED
# 打印未完成的任务列表,这些就是需要继续完成的任务
print(UNCOMPLETED)
- 随机产生2组各10个数字的列表,如下要求:
- 每个数字取值范围[10,20]
- 统计20个数字中,一共有多少个不同的数字?
- 2组之间进行比较,不重复的数字有几个?分别是什么?
- 2组之间进行比较,重复的数字有几个?分别是什么?
- 例如,两组数分别是[1,9,5,7,4]、[1,5,6,8],两组数一共有7个不同的数字,两组间不同的数字有5个,两组间重复的数字有2个
import random
g1 = []
g2 = []
# 生成两组随机数字
for i in range(10):
g1.append(random.randint(10, 20))
g2.append(random.randint(10, 20))
print(g1, g2, sep='\n')
# 使用集合(set)统计每组中不同的数字数量
# set()函数会去除列表中的重复元素,返回一个包含不重复元素的集合
s1 = set(g1)
s2 = set(g2)
# 使用集合的并集操作符(|)统计两组中不同的数字数量
print(s1 | s2)
# 使用集合的交集操作符(&)统计两组中相同的数字数量
print(s1 & s2)
# 使用集合的对称差集操作符(^)统计两组中的不同和重复的数字数量
print(s1 ^ s2)
26、用户输入一个数字
打印每一位数字及其重复的次数
# 获取用户输入的数字字符串,去除前后的空白字符和正负号
num = input('>>>').strip().lstrip('0+-')
print(type(num), num) # 打印输入数字的类型和内容
# 创建一个空字典,用于存储每个数字出现的次数
d = {}
# 遍历输入的数字字符串中的每个字符
for c in num:
# 如果字符不在字典的键中(即还未出现过),则将其添加到字典中并设置值为1
if c not in d.keys():
d[c] = 1
# 如果字符已经在字典的键中(即已经出现过),则将其值增加1
else:
d[c] += 1
print(d) # 打印每个数字出现的次数
# 创建另一个空字典,使用setdefault方法来统计每个数字出现的次数
d = {}
for c in num:
d[c] = d.setdefault(c, 0) + 1
print(d) # 打印每个数字出现的次数,与方法1的结果相同
# 创建第三个空字典,使用get方法来统计每个数字出现的次数
d = {}
for c in num:
d[c] = d.get(c, 0) + 1
print(d) # 打印每个数字出现的次数,与方法1的结果相同
# 创建第四个空字典,使用collections中的defaultdict来统计每个数字出现的次数
from collections import defaultdict
d = defaultdict(lambda: 0) # 使用默认值为0的字典来存储结果
for c in num:
d[c] += 1
print(d) # 打印每个数字出现的次数,与方法1的结果相同
27、数字重复统计
- 随机产生100个整数
- 数字的范围[-1000,1000]
- 升序输出这些数字并打印其重复的次数
# 导入random模块,该模块包含用于生成随机数的函数
import random
# 定义一个变量n,表示我们要生成的随机整数的数量,这里设置为100
n = 100
# 定义一个长度为n的列表nums,并初始化所有元素为None
nums = [None] * n
# 使用for循环来生成n个随机整数。range(n)产生一个从0到n-1的整数序列,我们在每个位置上生成一个随机数。
for i in range(n):
# random.randint(a, b)生成一个在[a, b]范围内的随机整数,包括a和b。
nums[i] = random.randint(-1000, 1000)
# 打印生成的随机数列表
print(nums)
# 定义一个字典counter,用于统计每个数字出现的次数
counter = {}
# 再次使用for循环来统计每个数字出现的次数
for x in nums:
# counter.get(x, 0)尝试获取字典中x键的值,如果x键不存在,则返回默认值0,然后在这个值上加1。
counter[x] = counter.get(x, 0) + 1
# 使用sorted函数和counter字典的items方法来得到一个升序的元素和它们出现次数的列表,然后打印这个列表。
print(sorted(counter.items()))
28、字符串重复统计
- 字符表
abcdefghijklmnopqrstuvwxyz
- 随机挑选2个字母组成字符串,共挑选100个
- 降序输出所有不同的字符串及重复的次数
# 导入Python的string模块,该模块包含了一些有用的字符串函数
import random
import string
# 创建一个字符表,包含小写字母a-z
alphabet = string.ascii_lowercase
# 打印字符表
print(alphabet)
# 另一种创建字符表的方式,范围是97-122(ASCII值),这是因为我们需要的是小写字母a-z
alphabet = bytes(range(97, 123)).decode()
# 打印字符表
print(alphabet)
# 创建并打印字符表"abcdefghijklmnopqrstuvwxyz"
alphabet = "abcdefghijklmnopqrstuvwxyz"
print(alphabet)
# 创建一个空列表,用于存储随机生成的字符串
words = []
# 在循环中,生成100个由两个随机字母组成的字符串,并添加到列表words中
for i in range(100):
# 两种随机选择字母的方式都可以,random.choices和random.sample都可以从列表中随机选择元素
# words.append(random.choice(alphabet)+random.choice(alphabet))
words.append("".join(random.choices(alphabet, k=2)))
# words.append("".join(random.sample(alphabet, k=2)))
print(words)
# 创建一个空字典,用于存储每个字符串及其出现的次数
d = {}
# 在循环中,遍历列表words,统计每个字符串出现的次数,并存储到字典d中
for word in words:
d[word] = d.get(word, 0) + 1
print(sorted(d.items(), reverse=True))
29、封装解构练习
- 从nums = [1, (2, 3, 4), 5]中,提取其中4出来
_, (*_, num), _ = [1, (2, 3, 4), 5]
print(num)
(_, [*_, num], _) = [1, (2, 3, 45), 5]
print(num)
- 从list(range(10))中,提取第二个、第四个、倒数第二个元素
_, a, _, b, *_, c, _ = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a, b, c)
- 环境变量JAVA_HOME=/usr/bin,返回环境变量名和路径
name, sep, path = "JAVA_HOME=/usr/bin".partition('=')
print(name, path)
评论区