2023-03-02 07:56:32 来源:程序员客栈
说在前面
“奥运排行榜”是一个源于实际的排序问题,每个国家的信息是一条记录,包含编号、国家/地区、人口数量、各奖牌数等数据项,根据不同的排序标准,对各条记录进行排序。
(资料图片)
教材程序采用一个二维数组来存储数据,每个元素表示一条记录,排序时可以对整条记录进行交换操作。教材还提供了“思考与练习”,继续研究不同数据结构和排序要求下,冒泡排序的不同实现方法,要求学生理解数据结构与算法的关系,值得深入探讨。
教材文本
教材处理
教材程序首先读取csv文件,再逐行将数据插入到二维数组a中,数组a的每个元素都是一个字符串列表,例如a[1]的值为["8", "中国", "136407", "51", "21", "28", "100"]。
程序在执行冒泡排序时,以金牌数为关键字进行降序排序,故需要先使用int()函数将a[j][3]转换成整数,再作比较。
因为a[0]的值是标题,所以不参与排序,这虽然能够解决问题,但造成了隐患,最好是不要把标题存储到a中,这样排序时就可以放心大胆地套用代码模板了。可以引导学生自行编程解决奥运排行榜问题,并比较其与教材程序的异同。
学生任务单
阅读教材P132例1“奥运排行榜”,思考如下问题:
(1)教材程序中变量a是何种数据结构?其元素值(例如a[3])是什么数据类型?
(2)教材程序是如何对数组a排序的?a[0]是否参与的排序?为什么?
(3)下列程序也能解决奥运排行榜问题,试比较其与教材程序的异同,并完成填空。
import csv
#数据读入
csvFile = open("jp.csv", "r") #打开相应数据文件
reader = list(csv.reader(csvFile)) # 转换成列表,以便跳过第一行
a = []
for item in reader[1:]:
a.append(item)
csvFile.close()
#排序
for i in range(1,len(a)):
for j in range(填空1):
if 填空2:
a[j], a[j+1] = 填空3
#数据写入
csvFile2 = open("jp2.csv","w", newline="")
writer = csv.writer(csvFile2, dialect="excel")
writer.writerow(reader[0]) #先写入标题
for i in a:
writer.writerow(填空4)
csvFile2.close()
(4)书中程序采用1个二维数组来存储数据,若改成以7个一维数组来存储数据,又该如何编程实现以金牌数为关键字进行降序排序功能?
参考代码如下,请将缺失的代码补充完整。
import csv
#数据读入
csvFile = open("jp.csv", "r") #打开相应数据文件
reader = list(csv.reader(csvFile)) #转换成列表,以便跳过第一行
a1 = [item[0] for item in reader[1:]] #编号
a2 = [填空1] #国家/地区
a3 = [item[2] for item in reader[1:]] #人口数量
a4 = [item[3] for item in reader[1:]] #金牌
a5 = [item[4] for item in reader[1:]] #银牌
a6 = [item[5] for item in reader[1:]] #铜牌
a7 = [填空2] #总数
#排序
for i in range(1,len(a1)):
for j in range(len(a1) - i):
if int(a4[j]) < int(a4[j+1]):
填空3(包含多行语句)
#数据写入
csvFile2 = open("jp2.csv","w", newline="")
writer = csv.writer(csvFile2, dialect="excel")
writer.writerow(reader[0]) #先写入标题
for i in range(len(a1)):
writer.writerow(填空4)
csvFile2.close()
(5)依然采用1个二维数组来存储数据,若将排序关键字改为“国民人均奖牌数”,并按升序排序,该如何编程实现以金牌数为关键字进行降序排序功能?
问题解析
(1)a是一个二维数组,其元素值是一个字符串数组,其中a[3]的值为["53", "美国", "32262", "36", "38", "36", "110"],a[3][3]也是一个字符串,可以使用int(a[3][3])将其转换成整数,表示金牌数量。
(2)书中程序采用冒泡排序算法,以金牌数为关键字,对数组a进行降序排序。因为a[0]存储的是标题,故不参与排序。程序的内层循环从下标1开始遍历数组,这样可以跳过a[0]。
(3)填空1:len(a) - i;
填空2:int(a[j][3]) < int(a[j+1][3]);
填空3:a[j+1], a[j];
填空4:i。
(4)填空1:item[1] for item in reader[1:];
填空2:item[1] for item in reader[1:];
填空3: a1[j], a1[j+1] = a1[j+1], a1[j]
a2[j], a2[j+1] = a2[j+1], a2[j]
a3[j], a3[j+1] = a3[j+1], a3[j]
a4[j], a4[j+1] = a4[j+1], a4[j]
a5[j], a5[j+1] = a5[j+1], a5[j]
a6[j], a6[j+1] = a6[j+1], a6[j]
a7[j], a7[j+1] = a7[j+1], a7[j]
填空4:[a1[i],a2[i],a3[i],a4[i],a5[i],a6[i],a7[i]]。
(5)参考代码如下:
import csv
#数据读入
csvFile = open("jp.csv", "r") #打开相应数据文件
reader = list(csv.reader(csvFile)) # 转换成列表,以便跳过第一行
a = []
for item in reader[1:]:
a.append(item)
csvFile.close()
#排序:关键字“国民人均奖牌数”,按升序排序
for i in range(1,len(a)):
for j in range(len(a) - i):
if int(a[j][6])/int(a[j][2]) > int(a[j+1][6])/int(a[j+1][2]):
a[j], a[j+1] = a[j+1], a[j]
#数据写入
csvFile2 = open("jp2.csv","w", newline="")
writer = csv.writer(csvFile2, dialect="excel")
writer.writerow(reader[0]) #先写入标题
for i in a:
writer.writerow(i)
csvFile2.close()
课后作业
任务(4)以7个一维数组来存储数据,当以金牌数为关键字进行降序排序时,不仅是对a4排序,其他6个数组的元素值也要相应变化,效率不高。因为这7个数组的结构一致,相同下标对应同一个国家,故我们可以增加一个索引数组b,专门用来存储这7个数组的下标,这样只需对索引数组b排序,数组a1-a7可以保持不变。输出数组元素时,只要设置正确的索引值,就能实现排序的效果。
这种排序方法被称为“索引排序”,参考代码如下,请将缺失的代码补充完整。
import csv
#数据读入
csvFile = open("jp.csv", "r") #打开相应数据文件
reader = list(csv.reader(csvFile)) #转换成列表,以便跳过第一行
a1 = [item[0] for item in reader[1:]] #编号
a2 = [填空1] #国家/地区
a3 = [item[2] for item in reader[1:]] #人口数量
a4 = [item[3] for item in reader[1:]] #金牌
a5 = [item[4] for item in reader[1:]] #银牌
a6 = [item[5] for item in reader[1:]] #铜牌
a7 = [填空2] #总数
b = [i for i in range(len(a1))] #设置索引数组
#排序
for i in range(1,len(a1)):
for j in range(len(a1) - i):
if int(a4[b[j]]) < int(a4[b[j+1]]):
填空3
#数据写入
csvFile2 = open("jp2.csv","w", newline="")
writer = csv.writer(csvFile2, dialect="excel")
writer.writerow(reader[0]) #先写入标题
for i in range(len(a1)):
writer.writerow(填空4)
csvFile2.close()
需要本文word文档、源代码和课后思考答案的,可以加入“Python算法之旅”知识星球参与讨论和下载文件,“Python算法之旅”知识星球汇集了数量众多的同好,更多有趣的话题在这里讨论,更多有用的资料在这里分享。
我们专注Python算法,感兴趣就一起来!
相关优秀文章:
阅读代码和写更好的代码
最有效的学习方式
Python算法之旅文章分类
- 加快虚拟仿真实训基地建设 启动职业学校信息化建设试点很必要
- “双减”后如何在满足学生多样需求方面做“加法”?
- 处于生理活跃期且心理发展不成熟 高校开设公共卫生必修课很必要
- 价格低于相应蔬菜零售价 西安投放约1万吨政府储备蔬菜
- 深受年轻消费群体所青睐 国潮风商品成为年货新选择
知识
- 他把银行卡卖给骗子,“黑吃黑”“截胡”十万元
- “老司机”4S店试驾豪车 结果油门当刹车撞了
- 新开工改造城镇老旧小区5.34万个
- 发动巡河志愿者2万余名 “用心护好每一条河”
- 假客服的套路:伪装成大平台客服,层层布局引人上钩
人物
- 浙江两轮核酸检测结果均为阴性 无新增本土阳性感染者
- 新疆阿克苏地区库车市发生4.1级地震 震源深度18千米
- 抵返哈尔滨人员须持48小时内核酸检测阴性证明
- 浙大紫金港校区已解封 有7337人有序离开该校区
- 2021年广东省第七届风筝锦标赛落幕
- 黑龙江讷河市启动全员核酸检测 目前讷河市全员核酸检测结果均为阴性
- 【同心粤港澳 携手大湾区】南头古城,搭建深港澳三地文化创意活动交流平台
- 重庆入河排污口整治工作推进至全市26个区县
- 四川省第二批政法队伍教育整顿:立案审查调查省级政法机关干警58人
- 长三角区域生态环境部门“云签约”长江大保护倡议书
- 古老长城重焕新生机
- 藏不住了!你同事里有许多“武林高手”……
- 浙江杭州2例无症状感染者系感染德尔塔变异株
- 喜马拉雅的深情和誓言
- 浪漫之城打造山海城一体新地标
- 让老年人更适应数字生活
- 内蒙古通辽市新增1例本土确诊病例、1例无症状感染者
- 徐州无新增确诊病例 核酸检测55515人结果均为阴性
- 甘肃培树“农家巧娘”增技能:返乡创业掌勺又“掌柜”
- 内蒙古通辽市科尔沁区一地调整为中风险地区
- 上海本轮疫情涉及闭环管理的医疗机构全面恢复门急诊
- 青年学生成艾滋病感染高发人群 “社会疫苗”如何打?
- 内蒙古满洲里新增本土确诊病例1例 当地开展第二轮大规模核酸检测
- 江西无新增本土确诊病例 上饶全面恢复正常生产生活秩序
- 中老铁路上会四国语言的列车长:用心维护中老友谊的桥梁
- 海南首次发现有环志的世界极危鸟种勺嘴鹬
- 一场“网络劝生者”和“网络劝死者”的战役
- 内蒙古通辽新增本土确诊和无症状感染者各1例 轨迹公布
- 江西中烟工业有限责任公司原总经理姚庆艳接受审查调查
- 宁夏45例新冠肺炎确诊病例均已治愈出院
- 内蒙古通辽市科尔沁区发现2名初筛阳性人员
- 生活在闹钟里的丈夫:自己迟一秒,渐冻症妻子就会多一分疼
- 辽宁新冠肺炎确诊病例零新增
- 11月28日16-24时,内蒙古新增本土确诊病例1例
- 奥密克戎毒株为何“需要关注”?现有防疫工具还有效吗?
- 黑龙江新增本土无症状感染者1例
- 这辈子一定要去趟这个公园 在这里“有种爱叫放手”
- 那年今日 | 一张漫画涨知识之11月29日
- 寒潮预警!我国中东部迎大范围降温 黑龙江等地降幅可达12℃
- 冷空气继续影响我国中东部 华北黄淮等地有雾和霾天气