1.编写函数,判断用户数入的3个数字是否为回文数。回文数是一个正向和逆向都相同的整数,如123454321,9889
错误写法:
def huiwen(string):
count=len(string)
center=(count-1)/2 #索引
print(int(center))
center1=-(count/2)
list_one=list(string) #转化为列表
list_two=
list_three=
for i in list_one :center :
list_two.append(i)
for i in list_one -1:center1 :
list_three.append(i)
if list_two == list_three:
print('是回文数')
这段代码的目的是检查一个字符串是否是回文,即正着读和反着读都一样的字符串。但是,这段代码中存在一些问题,导致了错误。我将逐一解释这些问题,并提供一个修正后的版本。
- 计算中心索引:
center=(count-1)/2
这行代码计算的是字符串中心的索引,但是当字符串长度为奇数时,中心是一个字符,而不是两个字符之间的空隙。因此,这里不需要减1。center1=-(count/2)
这行代码试图计算负的索引,但是Python不支持负的索引直接用在切片操作中。
- 列表推导式:
for i in list_one[:center]:
和for i in list_one[-1:center1]:
这两个循环试图分别创建前半部分和后半部分的列表,但是使用了错误的索引。
- 比较列表:
- 即使上面的问题被修正,
if list_two == list_three:
这行代码也不能正确判断字符串是否为回文,因为列表list_two
和list_three
的顺序是相反的。
下面是一个修正后的代码版本,这段代码将正确地检查一个字符串是否是回文:
- 即使上面的问题被修正,
def huiwen(string):
count = len(string)
center = count // 2 # 计算中心索引
# 分别获取前半部分和后半部分的字符串
front = string[:center]
back = string[-center:]
# 比较前半部分和反转的后半部分
if front == back[::-1]: # 使用[::-1]来反转字符串
print('是回文数')
else:
print('不是回文数')
# 测试函数
huiwen("上海自来水来自海上") # 应该输出 '是回文数'
def huiwen(string):
# 直接获取字符串长度
count = len(string)
# 根据字符串长度的奇偶性决定中心索引或索引对
if count % 2 == 0: # 偶数长度
center1 = count // 2 - 1
center2 = count // 2
else: # 奇数长度
center1 = center2 = count // 2
# 切片直接比较前半部分和翻转后的后半部分
first_half = string[:center2]
second_half = string[center1+1:][::-1] # 注意这里切片后反转以获得正确的后半部分
# 比较两部分是否相等
if first_half == second_half:
print('是回文字符串')
else:
print('不是回文字符串')
# 测试函数
huiwen("level") # 应输出:是回文字符串
huiwen("hello") # 应输出:不是回文字符串
这段代码首先计算字符串的中心索引,然后分别获取前半部分和后半部分的字符串。最后,通过比较前半部分和反转后的后半部分来确定字符串是否为回文。
second_half = string[center1+1:][::-1]
这段代码的目的是为了获取原字符串的后半部分,并将其反转,以便与前半部分进行比较以判断是否为回文。这里是分步解析:
-
string[center1+1:]
:center1
是根据字符串长度和奇偶性计算得到的一个索引位置。如果字符串长度是奇数,center1
就是中间索引;如果是偶数,它会是中间偏左的索引。center1 + 1
的目的是确保我们从中心点的下一个字符开始截取(对于奇数长度字符串,这是为了避免重复选取中间字符;对于偶数长度,则是从右半部分的实际开始处截取)。string[center1+1:]
表示从center1+1
这个位置直到字符串结束的所有字符。
-
[::-1]
:- 这是Python中的切片语法,用于序列的反向切片。
- 当应用于字符串时,
[::-1]
表示从字符串的末尾开始取到字符串的开头,步长为-1,即反向取出所有字符,实现字符串的反转。
综上,second_half = string[center1+1:][::-1]
先根据字符串的中心位置切取出后半部分,然后将这部分字符串反转,这样就可以和前半部分进行比较,以验证整个字符串是否为回文。简而言之, 进行了两次切片,第一次切片从中间值开始,第二次切片反向切片。Python不支持直接反向切片索引。
编写函数,输出1~100中偶数之和
def count_num():
count=0
for i in range(1,101):
if i%2==0:
count+=i
print(count)
2.编写函数,计算20x19x18x···x3的结果
用到了递归函数(函数内部调用了自身)
def func(num):
if num==1:
return 1
else:
return num*func(num-1)
不可使用break,continue因为其不是循环
3.编写函数,判断用户数入的3个数字是否能构成是三角形的三边
def sanjiao(*args):
if args[0] + args[1]>args[2]:
if args[0] + args[2]>args[1]:
if args[1] + args[2] > args[0]:
print ('是三角形')
else:
print('不是三角形')
else:
print('不是三角形')
else:
print('不是三角形')
4.编写函数,求2个正整数的最小公倍数
错误写法:
def minbeen(a,b=0):
for i in range(2,a+1):
for y in range(2,a+1):
if i*y==a:
print(f'{i}和{y}是{a}的最小公倍数')
if not(b==0):
return minbeen(b)
这段代码的目的是求最小公倍数,但是实现的方式是错误的。首先,这段代码实际上是找出能够相乘得到 a
的两个数,而不是求 a
的最小公倍数。其次,这段代码没有处理当 b
不为0的情况,即求两个数的最小公倍数。
最小公倍数(Least Common Multiple, LCM)是能被两个或多个整数共同整除的最小正整数。求两个数的最小公倍数通常需要先求出它们的最大公约数(Greatest Common Divisor, GCD),然后使用以下公式计算:
下面是一个修正后的代码版本,这段代码将正确地求出两个数的最小公倍数:
def gcd(a, b):
"""求最大公约数"""
while b:
a, b = b, a % b
return a
def lcm(a, b):
"""求最小公倍数"""
return abs(a * b) // gcd(a, b)
# 测试函数
print(lcm(12, 18)) # 应该输出 36,因为12和18的最小公倍数是36
这段代码首先定义了一个求最大公约数的函数 gcd
,然后定义了一个求最小公倍数的函数 lcm
。在 lcm
函数中,使用了前面提到的公式来计算最小公倍数。
在Python中,a, b = b, a % b
是一种常见的赋值操作,它同时更新了两个变量的值。这种操作通常用于算法中,特别是在计算最大公约数(GCD)的欧几里得算法中。
让我们逐步解释这个操作:
a % b
是取a除以b的余数。b, a % b
是一个元组,创建了一个包含两个元素的临时元组(b, a % b)
。a, b = b, a % b
是一个解包赋值操作,它将元组(b, a % b)
中的值分别赋给a
和b
。
具体步骤如下:
a
被赋值为b
,即a
变成了b
的当前值。b
被赋值为a % b
,即b
变成了a
(在赋值之前的原始值)除以b
(在赋值之前的原始值)的余数。
这个操作是欧几里得算法的关键步骤,它基于这样一个事实:两个整数的最大公约数与它们的差的最大公约数相同。因此,通过不断将较大数替换为两数之差,我们可以逐渐缩小问题的规模,直到其中一个数变为0。此时,另一个数就是原始两数的最大公约数。
例如,如果我们用这个算法来计算gcd(48, 18)
:
- 初始值:
a = 48
,b = 18
- 第一次迭代:
a = 18
,b = 48 % 18 = 12
- 第二次迭代:
a = 12
,b = 18 % 12 = 6
- 第三次迭代:
a = 6
,b = 12 % 6 = 0
当b
变为0时,算法结束,a
的值就是两数的最大公约数,即gcd(48, 18) = 6
。
5.兔子数列
错误写法:
#兔子数列
def countrabbit(num,month=1,num1=0):
if month<12:
if not(month<=2):
a=num+num
month+=1
return countrabbit(a,month,num)
else:
month+=1
a=num+num
return countrabbit(a,month)
else:
return num
print (countrabbit(2))
这个程序的目的是计算兔子数列(斐波那契数列的一个变种)在给定月份的数量,但存在一些逻辑错误和语法错误。以下是修正后的代码及对错误的详细说明:
修正后的代码
def count_rabbits(month=1, num=1, num_prev=0):
if month > 12:
return num
else:
# 第一个月和第二个月都是初始化值,从第三个月开始计算
if month <= 2:
num_next = num
else:
# 每月的兔子数量是前两个月数量之和
num_next = num + num_prev
# 递归调用,更新月份、当前月兔子数量和上个月兔子数量
return count_rabbits(month + 1, num_next, num)
print(count_rabbits(1))
错误说明
- 参数顺序和命名:原始函数参数顺序和命名不够直观。修正后将参数顺序调整为
month
、num
(当前月数量)、num_prev
(上个月数量),并更清晰地命名函数为count_rabbits
。 - 逻辑错误:原始代码中判断
if not(month<=2):
是为了从第三个月开始计算新兔子数量,但逻辑表达不恰当且导致了不必要的复杂性。修正后的代码通过简化条件直接计算每个月的兔子总数。 - 递归返回值:原始代码在递归调用时,没有正确传递所有必要的状态信息到下一次调用。修正后的代码确保每次递归调用都更新了
num
和num_prev
,以正确累计兔子数量。 - 基础案例处理:原始代码对于
month<12
的情况处理不当,修正后的代码通过检查month > 12
作为递归终止条件,更清晰地表达了当超过12个月时返回最终的兔子数量。 - 初始调用:考虑到兔子数列的计算特性,修正后的示例调用设置
month=1
作为默认值,并明确指定第一个月的兔子数量为1(而非2,因为通常斐波那契序列或类似兔子繁殖问题从0或1开始计算,这里假设初始为一对兔子)。
通过上述修改,代码现在能正确地计算并输出给定月份内兔子的预期数量。
兔子数列(通常称为斐波那契数列的一个变体)的基本假设是在理想状态下,从第3个月开始,每个月的兔子对数是前两个月的兔子对数之和。但这里的实现试图通过额外的参数和条件来控制流程,导致逻辑不够清晰。
下面是修正后的版本,以更简洁和准确的方式实现了兔子数列的计算:
def rabbit_count(n):
if n == 1 or n == 2:
return 1
else:
return rabbit_count(n-1) + rabbit_count(n-2)
print(rabbit_count(12))
但是,请注意,上述递归方法虽然逻辑上正确,但是当n较大时会非常慢,因为它涉及大量重复计算。对于实际应用,推荐使用迭代法或者利用动态规划减少重复计算,例如:
def rabbit_count_iterative(n):
if n == 1 or n == 2:
return 1
prev, curr = 1, 1
for _ in range(3, n + 1):
prev, curr = curr, prev + curr
return curr
print(rabbit_count_iterative(12))
这个迭代版本效率更高,可以快速准确地计算出前12个月的兔子对数。
6.归并排序
见:归并排序详解(附python实现)_归并排序递归法实验结果python-CSDN博客
实例
#兔子数列
#正序,但是数字是反向的,如果从1开始便利那么只会返回1,return后不可继续执行
'''
例如输入12
顺序:12,11,10,9,8,7,6,5,4,3,2,1
'''
def contra(month):
if month==0 or month==1:
return 1
else:
return contra(month-1)+contra(month-2)
print (contra(12))
def paix(li_1):
li_1.sort()
def countoushu():
count=0
for i in range(1,101):
if i%3==2:
count+=i
print (count)
countoushu()
def jiecheng(num):
if num==3:
return 3
else:
return num*jiecheng(num-1)
print (jiecheng(6))
# 计算1~100偶数之和
def contdouble():
count = 0
for i in range(1,101):
if i%2==0:
count+=i
return count
contdouble()
#思路1 逆置==倒置
def huiwen(num):
if num==num[::-1]:
return '是回文数'
else:
return '不是回文数'
print (huiwen('123454321'))
#思路二 如果是偶数则是前面的等于后面的,如果是奇数那么中间数前面的等于后面的
def huiwen1(num):
a=len(num)
if (a%2==0):
#字符串是一个可迭代对象
if (num[:int(a/2)]==num[::-1][:int(a/2)]):
print(num[:int(a / 2)-1:-1])
return '是回文数'
else:
return '不是回文数'
else:
if (num[:int(a/2)]==num[:int(a/2):-1]):
print (num[:int(a/2):-1])
#或者可以写成 if (num[:int(a/2)]==num[::-1][:2]):
return '是回文数'
else:
return '不是回文数'
print (huiwen1('12344321'))
#判断是否为三角形
def sanjiao(*args):
if args[0] + args[1] >args[2] and args[1] + args[2] >args[0] and args[0] + args[2] >args[1]:
return '是三角形'
else:
return '不是三角形'
print(sanjiao(3,4,5))
#求两个正整数的最小公倍数(肯定大于两个数的最大值)
def minbei(*args):
a = max(args)
while True:
if a/args[0] == args[1] and a/args[1] == args[0]:
return a
else:
a+=1
print (minbei(7,9))
def jiecheng(num):
if num==1:
return 1
else:
return num*jiecheng(num-1)
def maxlist(*args):
a = max(args)
b=min(args)
return f'最大值{a}最小值{b}'
print (maxlist(4,5,6,7))
#查找字符串
#方法一
def findstr(string,value):
if string.find(value):
return '找到了'
else:
return '没找到'
print(findstr('hello word','word'))
#方法二
def findstr1(string,value):
if value in string:
return '找到了'
else:
return '没找到'
print(findstr1('hello word','h'))