一.题目

输入:一个数组,和它的大小

输出:这个数组中最大子数组的和


例如

java 最大连续子数组 最大连续子数组和python_单元测试

 

 

 二.程序代码

最大连续子数组的特点:

(1)第一个不为负数

(2)如果前面数的累加加上当前数小于当前数,说明这次累加不是最大连续数组;如果前面数的累加加上当前数大于当前数,说明这次累加使最大和值增加了,符合情况。

我们可以根据此特点求连续子数组的最大和,

使用python进行计算

def Summax(lis):
    maxsum=int(lis[0])#定义存储当前的最大和
    presum=0#定义存放之前的累加值
    for i in lis:
        if presum<0:
            presum=int(i)#如果之前的累加和小于0,则替换当前值进行累加
        else:
            presum+=int(i)#如果是大于等于0的则需要将当前的数加到当前最大子数组中
        if presum>maxsum:
            maxsum=presum
    return maxsum

三.单元测试

python 中进行单元测试很简单,只需要导入unittest库,unittest是Python单元测试框架,类似于JUnit框架。

unittest中有4个重要的概念:test fixture, test case, test suite, test runner

Testcase:

一个TestCase的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码 (run),以及测试后环境的还原(tearDown)。元测试(unit test)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。

使用unittest编写python的单元测试代码,包括如下几个步骤:

1、编写一个python类,继承 unittest模块中的TestCase类,这就是一个测试类

2、在上面编写的测试类中定义测试方法(这个就是指的测试用例),每个方法的方法名要求以 test 打头,没有额外的参数。 在该测试方法中 调用被测试代码,校验测试结果,TestCase类中提供了很多标准的校验方法,如 最常见的assertEqual。

3、执行 unittest.main() ,该函数会负责运行测试,它会实例化所有TestCase的子类,并运行其中所有以test打头的方法。

测试代码:

import unittest
from unittest import TestCase
class MaxTest(TestCase):
    
    def test_1(self):
        list1=[-1,2,3,-4]
        self.assertEqual(Summax(list1),5)
    def test_2(self):
        list2=[-1,2,-5,3,-4]
        self.assertEqual(Summax(list2),3)
    def test_3(self):
        list3=[-1,20,-5,30,-4]
        self.assertEqual(Summax(list3),45)
    def test_4(self):
        list4=[-2,-3,-5,-1,-9]
        self.assertEqual(Summax(list4),-1)

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

结果:

java 最大连续子数组 最大连续子数组和python_测试用例_02

 

 

四.效能分析

使用cProfile进行效能测试

  • cProfile自python2.5以来就是标准版Python解释器默认的性能分析器。
  • 其他版本的python,比如PyPy里没有cProfile的。
  • cProfile是一种确定性分析器,只测量CPU时间,并不关心内存消耗和其他与内存相关联的信息。

代码如下:

import cProfile
#Sum.py
def Summax(lis):
    maxsum=int(lis[0])#定义存储当前的最大和
    presum=0#定义存放之前的累加值
    for i in lis:
        if presum<0:
            presum=int(i)#如果之前的累加和小于0,则替换当前值进行累加
        else:
            presum+=int(i)#如果是大于等于0的则需要将当前的数加到当前最大子数组中
        if presum>maxsum:
            maxsum=presum
    return maxsum
cProfile.run("Summax([-1,2,3,-4])")

结果:

java 最大连续子数组 最大连续子数组和python_测试用例_03

 

 ncalls:函数被调用的次数。如果这一列有两个值,就表示有递归调用,第二个值是原生调用次数,第一个值是总调用次数。
tottime:函数内部消耗的总时间。(可以帮助优化)
percall:是tottime除以ncalls,一个函数每次调用平均消耗时间。
cumtime:之前所有子函数消费时间的累计和。
filename:lineno(function):被分析函数所在文件名、行号、函数名。