数组中最大子数组之和

本篇博客主要内容为编写一个函数求一个数组中的最大连续子数组之和,并对该代码进行单元测试。

1、编写函数求数组的最大子数组之和。

代码如下:

def readFlie(file_path):
    '''
        此函数用于读取文件中的实数数据,并将其存入数组 num 中,函数的参数为文件路径
        并输出子数组个数、最大子数组之和、最大子数组在存储子数组的数组中的下标、最大子数组内容、最大子数组开始和结束的下标、选择是否显示所有组数组
    '''
    f = open(file_path, 'r', encoding='UTF8')
    f_read = f.read()
    # 读取文件数据,并保存与 f_read 中,其为 str 类型
    # print(f_read)
    judge = ['-','0','1','2','3','4','5','6','7','8','9','0']
    # 用于筛选掉分隔符
    num_str = ''
    # 用于将文件中的实数读取出来
    count_file = 0
    # 用于判断文件中的数据是否读完
    num = []
    for x in f_read:
        count_file += 1
        if x in judge:
            # 将需要的数据提取出来(’连续的数字‘ 或 ’负号加连续的数字‘)
            num_str += x
        elif x not in judge:
            # 将分隔符前的实数转换为 int 类型并放入数组 num 中
            num.append(int(num_str))
            num_str = ''
        if count_file == len(f_read):
            # 将最后一个数据也放入数组 num 中
            num.append(int(num_str))
            num_str = ''
    num_sons = []
    #   用于存入所有子数组之和
    for x in range(len(num)):
        for y in range(len(num)):
            #   双重循环用于取出所有不重复的子数组
            if num[x:x + y + 1] not in num_sons:
                num_sons.append(num[x:x + y + 1])
    print('子数组个数为:', len(num_sons))
    for x in range(len(num)):
        for y in range(len(num)):
            # 双重循环用于取出所有的子数组
            if num[x:x + y + 1] not in num_sons:
                num_sons.append(num[x:x + y + 1])
    num_sumSons = []
    #  用于存入所有子数组之和
    for x in num_sons:
        # 计算出所有子数组之和,并存入 num_sum 中
        num_sumSons.append(sum(x))
    print('最大的子数组之和为:', max(num_sumSons))
    count_numSumSons = 0
    #  用于定位最大子数组之和的数组在num_sons中的下标
    for x in num_sumSons:
        if x == max(num_sumSons):
            # 找到最大值并输出其下标
            print('在存储所有子数组的数组中的下标为:', count_numSumSons)
            break
        count_numSumSons += 1
    # 用于输出最大子数组
    max_numSon = []
    for x in num_sons:
        if sum(x) == max(num_sumSons):
            max_numSon = x
            print('最大子数组为:', max_numSon)
    # 用于输出最大子数组的第一个数和最后一个数在原数组中的下标
    Start = 0
    End = 0
    for Start in range(len(num) - len(max_numSon) + 1):
        # 若此处不 ’+1‘ ,则无法将固定长度的子数组读完
        End = Start + len(max_numSon)
        if num[Start:End] == max_numSon:
            print('最大子数组的第一个数和最后一个数在原数组中的下标分别为:', Start, End)
    isShow = int(input('是否需要显示所有子数组(1、是,0、否):'))
    if isShow == 1:
    # 用于输出所有子数组
        print('所有子数组如下:')
        count_show = 0
        for x in num_sons:
            print(count_show)
            print(x)
            count_show += 1
    return max(num_sumSons), Start, End

调用此函数的运行结果如下:

 

 文件中的数据如下:

 

 2、对此函数进行单元测试。

代码如下:

import unittest
from unittest import TestCase
from homeWork_test1.maindemo import readFlie

class Test(TestCase):
    def test_main(self):
        file_path = r'C:\Users\12044\Desktop\test.txt'
        result = readFlie(file_path)
        self.assertEqual(result, (111, 13, 18))

if __name__ == '__main__':
    unittest.main()

运行结果如下:

 

 此处弹出了一个警告,经过百度,虽然有解决方法,但具体原因尚未可知。

解决方法如下:

 

运行结果如下:

 

 3、对程序进行效能分析。

使用cProfile模块进行分析。

cProfile:基于lsprof的用C语言实现的扩展应用,运行开销比较合理,适合分析运行时间较长的程序。

使用cmd或者在pycharm的终端中输入:

 

 输出如下:

 

 

ncalls:表示函数调用的次数;
tottime:表示指定函数的总的运行时间,除掉函数中调用子函数的运行时间;
percall:(第一个percall)等于 tottime/ncalls;
cumtime:表示该函数及其所有子函数的调用运行的时间,即函数开始调用到返回的时间;
percall:(第二个percall)即函数运行一次的平均时间,等于 cumtime/ncalls;
filename:lineno(function):每个函数调用的具体信息。

posted @ 2021-03-14 09:11  二师弟_k  阅读(329)  评论(1)    收藏  举报