Logo

郎哥编程

编程案例——找出一组数的中位数

2020-04-23 363

1、编程需求

阿萌要开发一个程序,该程序可以从一组整数中,找出该组整数的中位数。

01.png

例如学生输入下面的一组整数:

02.png

程序对这一组整数按照从小到大的顺序排序:

03.png

程序从排序后的整数中找出中位数28,并输出28到shell窗口。

 

2、理解中位数

下面是一组学生投掷沙包的数据:

04.png

现在要统计一下这组学生投掷沙包的一般水平,该如何统计呢?

05.png

该组数的平均数为28.41,用28.41来表示这组学生投掷沙包的一般水平显然不太合适。因为我们可以看出,24.7更适合表示这组学生投掷沙包的一般水平。

使用该组数的平均数,不适合表示这组学生投掷沙包的一般水平,是因为该组数中有两个极端数值36.8和34.7。

当一组数中出现了极端数值时,用中位数作为这组数的一般水平会更合适。

中位数是按顺序排列的一组数据中居于中间位置的数,即在这组数据中,有一半的数据比它大,有一半的数据比它小

3、找出中位数的方法

要找出一组数的中位数,需要先对这组数按照大小排序,或从大到小排序,或从小到大排序。

如果这组数的个数是奇数,则中间那个数就是这组数的中位数;如果这组数的个数是偶数,则中间那2个数的平均值就是这组数的中位数。

用程序从一组数找出中位数的具体步骤如下:

(1)程序接收学生输入的一组数;

(2)程序对该组数按从小到大排序;

(3)如果该组数的个数是奇数,输出该组数中间的那个数;

(4)如果该组数的个数是偶数,求出中间那2个数的平均值,输出平均值。

06.png

4、冒泡排序算法

要从一组数中找出中位数,需要对这一组数进行大小排序,或者从小到大排序,或者从大到小排序。

对一组数进行排序,对人来说非常容易,通过眼睛的观察和数的比较,就可以完成一组数的排序。

要让计算机完成一组数的排序,就需要人来编写程序,将排序的算法编写为程序,计算机才能完成对一组数的排序。

排序有很多算法,让我们来看一个冒泡排序算法,该算法一次比较两个元素,如果他们的顺序错误就把他们交换过来,重复访问该组数所有的数并进行比较和交换,直到再没有数需要交换,说明该组数已经排序完成。

对下面的一组数用冒泡排序算法,并按照从小到大的顺序排序。

07.png

排序前的一组数,我们称为原始数列,每两个数进行一次比较,称为一轮比较。

08.png

第一轮比较:23与34比较,23小于34,两个数不用交换位置。

09.png

第二轮比较:34与5比较,因为34大于5,因此34和5交换位置。

10.png

11.png

第三轮比较:34与7比较,因为34大于7,因此34与7交换位置。

12.png

13.png

第四轮比较:比较34和56,因为34小于56,两个数不用交换位置。

14.png

在前面的四轮比较中,从数列左侧的第一个数开始,顺序两两比较两个数的大小,如果前面一个数比后面一个数大,就交换两数的位置,直到数列的最后一个数比较完毕。

这四轮比较下来,称为一趟比较。如果在该趟比较中,存在两个数交换位置的情况,就需要进行下一趟比较,直到再没有数字进行交换,算法结束。

因为在第一趟比较中,存在两数的位置交换,因此还需要进行第二趟的比较。

第二趟比较

第二趟比较也是从数列左侧的第一个数开始,顺序两两比较两个数的大小。不过第二趟比较就不需要再比较数列右侧的最后一个数了,因为在第一趟比较的过程中,该数列最大的数已经被交换到数列右侧最后的一个位置了。

15.png

第一轮比较:比较23和5,因为23大于5,因此23和5交换位置。

16.png

17.png

第二轮比较:比较23和7,因为23大于7,因此23和7交换位置。

18.png

19.png

第三轮比较:比较23和24,因为23小于24,两个数不用交换位置。

20.png

至此,第二趟比较完成。最后的一个数56就不用比较了,因为56在第一趟比较中就已经为自己找到了正确的位置。

从第三轮的比较结果来看,排序已经完成,每个数都自己找到了正确的位置。已经不需要再进行第三趟比较了。

5、for循环嵌套结构

冒泡排序算法需要对待排序的一组数,进行多趟数的比较,在每趟的比较过程中,需要按顺序两两比较该组数中相邻的两个数。

现在我们需要把冒泡排序算法编写为程序,算法的多趟比较可以用for循环来实现。但这里会存在一个问题,就是在每趟的循环中,还需要一个循环来完成每趟顺序两两比较该组数中相邻的两个数,这个循环是在每趟循环的循环体内。

21.png

要解决上面的问题,就需要用到for循环的嵌套结构。for循环的嵌套结构是在for循环体内再嵌套一个for循环,这样就会有两层循环,第一层循环称为外循环,第二层循环称为内循环。

for循环嵌套结构语法如下:

22.png

首先外循环的第一轮触发内循环,内循环将一直执行到完成为止,然后,外循环的第二轮再次触发内循环,此过程不断重复直到外循环结束,使用嵌套循环时,只有在内循环完全结束后,外循环才会执行下一趟循环。

23.png

案例01的代码演示了for循环嵌套结构的使用。

案例01输出九九乘法表,代码使用了两层循环,外层循环范围为1~10,控制九九乘法表行的输出,内层循环范围为1~i+1,控制乘法表列的输出。

在案例01代码中,调用print函数输出乘法表时,另外传入了一个参数“end= ""”,传入该参数是告诉print函数,在内容输出完成后,不要输出换行符。下次调用print函数输出内容时,还是在这一行输出,并不另起一行输出内容。

print函数的默认输出,是在输出内容后,再另外输出一个换行符,下次输出内容时会另起一行。如果在调用print函数时,传入参数“end= ""”,print函数就不会再另外输出一个换行符。

6、冒泡排序算法的代码实现

掌握了for循环嵌套结构的用法,就可以开始编写冒泡排序算法的代码了。冒泡排序算法用函数来实现,方便主程序的调用,冒泡排序算法函数代码保存到sort.py模块文件。

冒泡排序算法的流程图:

24.png


冒泡排序算法代码:

'''
程序文件:sort.py
功能描述:冒泡排序
代码编写时间:2020/04/20
作者:编程训练营
'''
# 定义冒泡排序函数
# 函数传入待排序的整数列表nums
def bubble_sort(nums):
 
    '''
    外层循环控制比较趟数
    需要比较nums列表长度减1趟
    '''
    for i in range(0,len(nums)-1):
        '''
        内层循环控制每一趟排序多少次
        每一趟排序都会把较大的数值移动到列表后面
        第i趟排序循环次数为列表长度减去已经排过序的i个元素
        如果第j个元素大于第j+1个元素,则交换
        '''
        for j in range(0,len(nums)-i-1):
            if nums[j] > nums[j+1]:
                # 交换第j和第j+1个元素        
                temp = nums[j]
                nums[j] = nums[j+1]
                nums[j+1] = temp
    return nums

代码解读

函数传入列表nums,nums存储了待排序的一组整数。然后用外层for循环结构控制列表元素的比较趟数,比较趟数为待排序列表元素的个数减去1,在每趟比较中,用内层for循环遍历待排序列表元素,并进行比较和位置交换,循环范围介于0到列表元素的个数减去1,再减去外层循环当前执行的比较趟数,因为i趟排序过程中,已经把i个较大的数交换到列表length-i的列表序号范围,无需再比较和交换。

7、程序流程图

25.png


(1)程序输出提示信息,提示信息为“输入quit退出程序,输入begin开始找中位数”;

(2)获取学生输入的内容,赋值给option;

(3)判断option的值是否是quit,若是quit,程序结束;

(4)若不是quit,调用函数要求学生输入一组整数;

(5)调用排序算法函数对学生输入的一组整数排序;

(6)调用函数找出中位数,并输出中位数;

(7)再次等待学生的输入。

26.png

(1)创建一个空列表list,用于存储学生输入的一组整数;

(2)输出提示信息,提示信息内容为“请输入一个整数,输入end可结束输入”;

(3)接收学生的输入,输入内容赋值给num;

(4)判断num是否是整数,如果是整数将num加入list,再次进入输入状态。如果不是整数,判断num是否等于end,如果是end,返回list,函数执行结束。

27.png

(1)判断list元素的个数是否是奇数,如果是奇数,转第2个步骤,否则转第3个步骤;

(2)取出list中间的元素,函数返回该元素的值。取list中间元素的方法是:list元素的索引为list元素的个数除以2并取整;

(3)取出list中间两个元素。取中间两个元素的方法是:第一个元素的索引是list元素的个数除以2取整后减1,第二个元素的索引是第一个元素的索引加1;

(4)返回两个元素的平均值。

 8、程序代码及解读

程序代码如下:

'''
程序文件:main.py
功能描述:找出一个数的中位数
代码编写时间:2020/04/22
作者:编程训练营
'''
 
# 导入sort模块
import sort  as sort
# 定义getnums函数,获取一组整数
def getnums():
    # 创建一个空的list
    list = []
    # 输出提示信息
    print("请输入一个整数,输入end可结束输入")
    # 循环输入整数
    while(True):
        # 获取输入
        num = input("请输入:")
        # 判断num是否全部是数字字符
        if num.isdigit():
            list.append(int(num))
        elif num == "end":
            break;
    return list
 
# 定义find函数
# 从已排序的列表中找出中位数
def find(inlist):
    # 获取列表元素的个数
    length = len(inlist)
    # 判断length是否是奇数
    if  length % 2 != 0:
        # 如果是奇数
        # 返回索引为列表元素个数除以2的列表元素
        return inlist[len(inlist)//2]
    else:
        # 获取列表中间元素第一个元素
        num1 = inlist[len(inlist)//2-1]
        # 获取列表中间元素第二个元素
        num2 = inlist[len(inlist)//2]
        # 求两个元素的平均值
        average = (num1+num2)//2
        return average
 
# 程序入口
if __name__ == '__main__':
 
    while(True):
        # 输出提示信息
        print("输入quit退出程序,输入begin开始找中位数")
        # 等待学生输入
        option = input("请输入:")
        # 如果输入是quit,退出程序
        if option == "quit":
            break;
        # 如果输入是begin,开始找中位数
        if option == "begin":
            # 调用函数getnums获取一组整数
            nums = getnums()
            # 调用sort模块的sort函数对列表元素排序
            nums = sort.bubble_sort(nums)
            # 调用find函数找出中位数
            num = find(nums)
            # 输出中位数
            print("%s的中位数:%d" % (nums,num))

代码解读

代码定义了两个函数,分别是getnums函数和find函数。

getnums函数实现获取学生输入一组整数的功能。函数首先创建一个空的list列表,用于存储学生输入的整数。然后使用while循环来获取学生输入的多个整数,在while循环体内,使用input函数获取学生输入的内容,并赋值给num,程序使用num的isdigit方法,判断num的内容是否全部是数字字符,如果全部是数字字符,使用int函数将num转换为整数添加到list。如果num的内容是end,说明整数序列已经输入完成,调用break语句退出循环,函数返回list。

find函数实现从已排序的列表中找出中位数的功能。函数首先判断列表元素个数的奇偶性,如果列表元素的个数是奇数,索引为列表元素个数除以2取整后的列表元素,就是该整数序列的中位数。如果列表元素的个数是偶数,该整数序列的中位数是中间两个数的平均值,函数求出两个数的平均值并返回。

代码使用了import语句导入了sort.py模块,该模块定义了bubble_sort函数,该函数实现了冒泡排序算法。

程序的主体代码建立一个while循环,让程序一直处于运行状态。在while循环体内,首先会要求学生输入“quit”或“begin”,并赋值给option。

如果option的内容为“quit”,则调用break语句退出循环,程序结束。

如果option的内容为“begin”,调用getnums函数要求学生输入一组整数,函数会返回已存储一组整数的列表,然后调用sort模块的bubble_sort函数对列表内的整型进行排序,最后调用find函数从已排序的列表中找出中位数。

28.png


代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论