软件工程日报(5.1)
一实验目的
l 使学生熟悉Python环境的安装与配置,熟悉Python解释器的使用。
l 使学生掌握Python控制语句、函数结构等的基本语法知识和使用。
l 使学生掌握Python的基本数据类型、列表、元组、字典和集合等的基本应用。
二实验环境及实验准备
l 所需软件环境为Pyhton 3.x等;
l 掌握Python控制语句和函数结构等基本语法知识;
l 掌握Python的输入输出;
l 掌握Python的基本数据类型、列表、元组、字典和集合等;
三实验内容
(一)、练习安装Python解释器
【实验截图】
(二)、练习搭建Python+Eclipse+pydev编程环境
【实验截图】
(三)、练习安装Python扩展库
【实验截图】
把库安装完才看见要截图,只能截一个安装完成的屏了
(四)、【Python0002】排列组合序列
【题目描述】
用户输入整数n(1<=n<=26)和整数m(m<=n),然后输入n个不同的字母,请编写程序输出在这n个字母中选择m个字母的所有排列序列和组合序列。
【源代码程序】
from itertools import permutations, combinations
def get_input():
# 获取用户输入
n = int(input("请输入整数n(1<=n<=26):"))
m = int(input("请输入整数m(m<=n):"))
# 检查输入的有效性
if n < 1 or n > 26 or m > n:
print("输入不合法,请确保1<=n<=26且m<=n。")
return None, None
# 输入n个不同的字母
print(f"请输入{n}个不同的字母,用空格分隔:")
letters = input().split()
# 检查字母数量和唯一性
if len(letters) != n or len(set(letters)) != n:
print("输入的字母数量不正确或有重复,请重新输入。")
return None, None
return n, m, letters
def display_sequences(n, m, letters):
# 生成并打印所有排列
print("\n所有排列序列:")
for p in permutations(letters, m):
print(''.join(p))
# 生成并打印所有组合
print("\n所有组合序列:")
for c in combinations(letters, m):
print(''.join(c))
if __name__ == "__main__":
n, m, letters = get_input()
if n and m and letters:
display_sequences(n, m, letters)
【运行测试】
(五)、【Python0003】蒙特·卡罗法计算圆周率
【题目描述】
蒙特·卡罗方法是一种通过概率来得到问题近似解的方法,在很多领域都有重要的应用,其中就包括圆周率近似值的计问题。假设有一块边长为2的正方形木板,上面画一个单位圆,然后随意往木板上扔飞镖,落点坐标(x,y)必然在木板上(更多的时候是落在单位圆内),如果扔的次数足够多,那么落在单位圆内的次数除以总次数再乘以4,这个数字会无限逼近圆周率的值。这就是蒙特·卡罗发明的用于计算圆周率近似值的方法。编写程序,模拟蒙特·卡罗计算圆周率近似值的方法,输入掷飞镖次数,然后输出圆周率近似值。
【源代码程序】
import random
def monte_carlo_pi(n):
inside_circle = 0 # 落在单位圆内的点数
for _ in range(n):
# 生成一个在[-1, 1]范围内的随机x坐标和y坐标
x = random.uniform(-1, 1)
y = random.uniform(-1, 1)
# 计算点到原点(0,0)的距离,判断是否在单位圆内
if x**2 + y**2 <= 1:
inside_circle += 1
# 根据落在圆内的点数与总点数的比例来估计π
pi_approximation = 4 * (inside_circle / n)
return pi_approximation
# 示例:用户输入的掷飞镖次数
n = int(input("请输入掷飞镖的次数:"))
# 计算并输出圆周率的近似值
approximate_pi = monte_carlo_pi(n)
print(f"根据{n}次掷飞镖实验,得到的π近似值为:{approximate_pi}")
【运行测试】
(六)、【Python0004】验证6174猜想
【题目描述】
1955年,卡普耶卡(D.R.Kaprekar)对4位数字进行了研究,发现一个规律:对任意各位数字不相同的4位数,使用各位数字能组成的最大数减去能组成的最小数,对得到的差重复这个操作,最终会得到6174这个数字,并且这个操作最多不会超过7次。请编写程序验证这个猜想。
【源代码程序】
def kaprekar_process(num):
if not 1000 <= num <= 9999 or len(set(str(num))) != 4:
raise ValueError("输入必须是一个4位数且各位数字各不相同。")
count = 0
while num != 6174:
# 将数字排序,得到最小数和最大数
num_str = ''.join(sorted(str(num)))
min_num = int(num_str)
max_num = int(''.join(sorted(str(num), reverse=True)))
# 计算差值
num = max_num - min_num
# 确保结果仍然是一个4位数,通过在前面补0
num = num % 10000
count += 1
# 防止无限循环,最多尝试7次
if count > 7:
return -1
return count
try:
num = int(input("请输入一个4位数,且各位数字不相同:"))
steps = kaprekar_process(num)
if steps != -1:
print(f"经过{steps}次操作后,得到了6174。")
else:
print("ERROR")
except ValueError as e:
print(e)
【运行测试】
(七)、【Python0005】模拟页面调度LRU算法
【题目描述】
所谓LRU算法,是指在发生缺页并且没有空闲主存块时,把最近最少使用的页面换出主存块,腾出地方来调入新页面。
问题描述:一进程获得n个主存块的使用权,对于给定的进程访问页面次序,问当采用LRU算法时,输出发生的缺页次数。
【源代码程序】
from collections import OrderedDict
def lru_page_faults(page_sequence, memory_size):
# 初始化一个OrderedDict来存储当前在内存中的页面及其访问时间(这里用索引表示时间)
memory = OrderedDict()
# 缺页计数器
page_faults = 0
for page in page_sequence:
# 如果页面已经在内存中,更新其访问时间(移到末尾)
if page in memory:
del memory[page] # 移除旧记录,以便重新插入时放于末尾
else:
# 如果内存已满,移除最久未使用的页面(即最前面的页面)
if len(memory) == memory_size:
memory.popitem(last=False) # 移除最早访问的页面
page_faults += 1 # 发生缺页
else:
page_faults += 1 # 新的页面访问,且内存未满,也计为缺页
# 将当前页面加入到内存中(表示最近访问)
memory[page] = None
return page_faults
# 示例
page_sequence = [1, 2, 3, 4, 2, 1, 5, 6, 2, 3]
memory_size = int(input("请输入主存块数量n(n>1):"))
print("缺页次数:", lru_page_faults(page_sequence, memory_size))
【运行测试】
(八)、【Python0006】爬楼梯
【题目描述】
假设一段楼梯共n(n>1)个台阶,小朋友一步最多能上3个台阶,那么小朋友上这段楼梯一共有多少种方法。
【源代码程序】
def count_ways_to_climb_stairs(n):
# 处理基础情况
if n <= 0:
return 0
elif n == 1:
return 1
elif n == 2:
return 2
elif n == 3:
return 4
# 初始化动态规划数组
ways = [0] * (n + 1)
ways[1], ways[2], ways[3] = 1, 2, 4
# 从第4个台阶开始计算
for i in range(4, n + 1):
ways[i] = ways[i - 1] + ways[i - 2] + ways[i - 3]
return ways[n]
n = int(input("请输入楼梯的台阶数n(n>1):"))
result = count_ways_to_climb_stairs(n)
print(f"上到{n}个台阶的方法数为:{result}")
【运行测试】
(九)、【Python0007】杨辉三角形
【题目描述】
输出n(0<n)行杨辉三角形,n由用户输入。
【源代码程序】
def generate_pascals_triangle(n):
"""生成n行的杨辉三角"""
triangle = []
for row_num in range(n):
# 每一行的第一个元素总是1
row = [1] * (row_num + 1)
for j in range(1, row_num):
# 中间的元素是上一行的两个对应元素之和
row[j] = triangle[row_num - 1][j - 1] + triangle[row_num - 1][j]
triangle.append(row)
return triangle
def print_pascals_triangle(triangle):
"""打印杨辉三角"""
for row in triangle:
print(' '.join(map(str, row)).center(2 * len(triangle[-1])))
# 用户输入
n = int(input("请输入想要输出的杨辉三角形的行数n(0<n):"))
if n <= 0:
print("输入的行数应大于0,请重新输入。")
else:
pascals_triangle = generate_pascals_triangle(n)
print_pascals_triangle(pascals_triangle)
【运行测试】
(十)、【Python0008】筛法求素数
【题目描述】
用户输入整数n和m(1<n<m<1000),应用筛法求[n,m]范围内的所有素数。
【源代码程序】
def sieve_of_eratosthenes(n, m):
if not (1 < n < m < 1000):
raise ValueError("输入的整数n和m应满足1<n<m<1000的条件。")
# 初始化一个布尔数组,索引表示数字,初始值为True表示可能是素数
is_prime = [True] * (m + 1)
is_prime[0], is_prime[1] = False, False # 0和1不是素数
# 筛选过程,p^2之前的已经考虑过了,所以从p^2开始,步长为p
for p in range(2, int(m**0.5) + 1):
if is_prime[p]:
for i in range(p*p, m + 1, p):
is_prime[i] = False
# 收集[n, m]范围内的素数
primes_in_range = [x for x in range(n, m + 1) if is_prime[x]]
return primes_in_range
# 示例使用
n = int(input("请输入整数n(1<n):"))
m = int(input("请输入整数m(n<m<1000):"))
try:
primes = sieve_of_eratosthenes(n, m)
print(f"[{n},{m}]范围内的素数有:{primes}")
except ValueError as e:
print(e)
【运行测试】
(十一)、【Python0009】查找鞍点
【题目描述】
对于给定5X5的整数矩阵,设计算法查找出所有的鞍点的信息(包括鞍点的值和行、列坐标,坐标从1开始)。
提示:鞍点的特点:列上最小,行上最大。
【源代码程序】
def input_matrix(rows, cols):
"""从用户处输入矩阵数据"""
matrix = []
print(f"请输入一个{rows}x{cols}的整数矩阵:")
for i in range(rows):
row = list(map(int, input(f"请输入第{i + 1}行,用空格分隔每个数字: ").split()))
if len(row) != cols:
print("输入错误,请确保每行有正确的列数。")
return None
matrix.append(row)
return matrix
def find_saddle_points(matrix):
"""查找并返回矩阵中的所有鞍点信息"""
rows = len(matrix)
cols = len(matrix[0])
saddle_points = []
for i in range(rows):
for j in range(cols):
# 检查是否为行中的最大值
is_max_in_row = all(matrix[i][j] >= matrix[i][k] for k in range(cols) if k != j)
# 检查是否为列中的最小值
is_min_in_col = all(matrix[i][j] <= matrix[k][j] for k in range(rows) if k != i)
if is_max_in_row and is_min_in_col:
saddle_points.append((matrix[i][j], i + 1, j + 1))
return saddle_points
def main():
matrix = input_matrix(5, 5)
if matrix:
saddle_points = find_saddle_points(matrix)
if saddle_points:
print("找到的鞍点如下:")
for point in saddle_points:
print(f"值:{point[0]},位置:({point[1]}, {point[2]})")
else:
print("矩阵中没有鞍点。")
else:
print("矩阵输入有误。")
if __name__ == "__main__":
main()
【运行测试】
(十二)、【Python0010】正整数的因子展开式
【题目描述】
编写程序,输出一个给定正整数x(x>1)的质因子展开式。
【源代码程序】
a=int(input())
b=str(a)
num=[]
i=1
while i <= a:
if a%i == 0:
a = a/i
num.append(i)
i = 1
i+=1
b+='='+str(num[1])
for j in num[2:]:
b+="*"+str(j)
print(b)
【运行测试】
(十三)、【Python0011】牛顿迭代法
【题目描述】
编写程序,使用牛顿迭代法求方程在x附近的一个实根。
【源代码程序】
def newton_raphson(a, b, c, d, x0, tol=1e-8, max_iter=100):
def f(x):
return a*x**3 + b*x**2 + c*x + d
def f_prime(x):
return 3*a*x**2 + 2*b*x + c
x_n = x0
for _ in range(max_iter):
x_n1 = x_n - f(x_n) / f_prime(x_n)
if abs(x_n1 - x_n) < tol:
return x_n1 # 收敛,返回结果
x_n = x_n1 # 更新迭代值
return None # 未在最大迭代次数内收敛
# 示例使用
a, b, c, d = 1, -6, 11, -6 # 示例方程 x^3 - 6x^2 + 11x - 6 = 0 的系数
x0 = 1 # 初始猜测值
root = newton_raphson(a, b, c, d, x0)
if root is not None:
print(f"方程的实根约为: {root}")
else:
print("未找到根或迭代未收敛。")
【运行测试】
四实验分析及问题思考
【Python0012】针对Python中的列表、元组、字典、集合、字符串,请以条目形式从各方面对比它们之间的异同。
【答案】数据结构与类型
列表: 动态数组,可以存储不同类型的数据,用方括号[]表示。例如:[1, "text", True, 3.14]
元组: 不可变的序列,也可以存储不同类型的数据,用圆括号()表示。例如:(1, "text", True, 3.14)
字典: 键值对的集合,键必须唯一且不可变(如字符串、数字、元组),值可以是任何类型,用花括号{}表示。例如:{"name": "Alice", "age": 30, "city": "New York"}
集合: 无序且不重复元素的集合,用花括号{}表示,但若只包含一个元素需要加逗号以区分字典。例如:{1, 2, 3} 或 {4,}(表示集合中只有一个元素4)
字符串: 一串字符,用单引号''或双引号""表示。例如:"Hello, World!"
可变性
列表: 可变,可以增加、删除、修改元素。
元组: 不可变,一旦创建,其内容不能更改。
字典: 可变,可以添加、删除、修改键值对。
集合: 可变,可以添加、删除元素,但元素必须是可哈希的且唯一。
字符串: 不可变,字符串的每个字符不能单独修改,但可以通过切片、拼接等操作生成新字符串。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下