“奥运排行榜”教学思路

Python算法之旅

共 4823字,需浏览 10分钟

 ·

2023-02-25 12:26

说在前面

“奥运排行榜”是一个源于实际的排序问题,每个国家的信息是一条记录,包含编号、国家/地区、人口数量、各奖牌数等数据项,根据不同的排序标准,对各条记录进行排序。

教材程序采用一个二维数组来存储数据,每个元素表示一条记录,排序时可以对整条记录进行交换操作。教材还提供了“思考与练习”,继续研究不同数据结构和排序要求下,冒泡排序的不同实现方法,要求学生理解数据结构与算法的关系,值得深入探讨。

教材文本

教材处理

教材程序首先读取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算法之旅文章分类

浏览 36
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报