软件工程第二次作业-最大连续子数组单元测试

2024年4月10日

作业信息 沈阳航空航天大学计算机学院2024软件工程作业
课程目标 熟悉一个“高质量”软件的开发过程
作业目标 单元测试练习

题目要求:
题目(1):最大连续子数组和(最大子段和)
1.背景
问题: 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为: Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n
例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,最大子段和为20。

2.最大连续子数组和问题解决

include

include

define INT_MIN -9999

define MAX_SIZE 100

using namespace std;

struct INDEX{
int low;
int high;
int sum;
};

struct INDEX Find_Max_Crossing_Subarray(int* arr, struct INDEX c) {
int mid = (c.high + c.low) / 2;
int i = mid;
int j = mid + 1;
int left_sum = INT_MIN;
int right_sum = INT_MIN;
int sum = 0;
int low = c.low;
int high = c.high;
for (; i >= low; i--) { //找出左半边数组的最大子数组,从mid开始
sum = sum + arr[i];
if (sum > left_sum) {
c.low = i;
left_sum = sum;
}
}
sum = 0;
for (; j <= high; j++) { //同理,找出右半边
sum = sum + arr[j];
if (sum > right_sum) {
c.high = j;
right_sum = sum;
}
}
c.sum = left_sum + right_sum;
if (left_sum > c.sum)
c.sum = left_sum;
else if (right_sum > c.sum)
c.sum = right_sum;
return c;
}

struct INDEX Find_Max_Subarray(int* arr, struct INDEX c) {
if (c.high == c.low) {
c.sum = c.low;
return c;
}
int mid = (c.high + c.low) / 2;
struct INDEX left;
left.high = mid;
left.low = c.low;
struct INDEX right;
right.high = c.high;
right.low = mid + 1;
left = Find_Max_Subarray(arr, left);
right = Find_Max_Subarray(arr, right);
c = Find_Max_Crossing_Subarray(arr, c);
if (left.sum >= right.sum && left.sum >= c.sum)
c.sum = left.sum;
else if (right.sum >= left.sum && right.sum >= c.sum)
c.sum = right.sum;
if (c.sum < 0)
c.sum = 0;
return c;
}

int main() {
int n = 0;
int num = 0;
int arr[MAX_SIZE];
cin >> n;
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
struct INDEX c;
c.high = n;
c.low = 0;
c = Find_Max_Subarray(arr,c);
std::cout << c.high << " " << c.low << " " << c.sum;
return 0;
}
3.测试用例
使用Google Test项目进行单元测试,采用条件覆盖对源程序进行测试。使用递归的方式将原问题分解为一个个子问题及子数组。将数组从中间分割开为两部分,左端数组和右端数组,由于最大连续子数组可能包括左端和右端,需要单独求解判断。
找出中间最大连续子数组、左端最大子数组和右端最大子数组,比较找出最大的一项,返回最大子数组至上一级,再归并再次比较出最大的一项直到回到原数组为止。

代码测试用例及结果如下:
测试用例 测试结果 测试条件
{ -2,11,-4,13,-5,-2 } 20 最大连续子数组位于数组中间
{ 5,4,-1,7,8 } 23 原数组为最大
{ 31, -41,59 ,26,-53,58,97,-93,-23,84 } 187 最大连续子数组位于数组左端
{10} 10 只包含一个元素
测试代码如下:

include "pch.h"

TEST(Test1) {
int arr[6] = { -2,11,-4,13,-5,-2 };
struct INDEX c;
c.high = 5;
c.low = 0;
EXPECT_EQ(20, Find_Max_Crossing_Subarray(arr,c).sum);
}

TEST(Test2) {
int arr[5] = { 5,4,-1,7,8 };
struct INDEX c;
c.high = 4;
c.low = 0;
EXPECT_EQ(23, Find_Max_Crossing_Subarray(arr, c).sum);
}

TEST(Test3) {
struct INDEX c;
int arr0[10] = { 31, -41,59 ,26,-53,58,97,-93,-23,84 };
c.high = 9;
c.low = 0;
EXPECT_EQ(187, Find_Max_Crossing_Subarray(arr0, c).sum);
}

TEST(Test4) {
struct INDEX c;
int arr0[10] = { 10 };
c.high = 0;
c.low = 0;
EXPECT_EQ(10, Find_Max_Crossing_Subarray(arr0, c).sum);
}
测试运行结果如下:

4.总结
通过这次实验,我对C++的单元测试有了更深入的理解。我学习了如何使用Google Test框架进行单元测试,并通过实践了解了单元测试在软件开发中的重要性。
在实验过程中,我首先编写了一些基本的C++函数,然后为这些函数编写了单元测试。我发现,虽然编写测试用例需要一些时间,但这些测试用例在后期的代码修改和维护中起到了非常重要的作用。每当我修改了函数的实现,我都可以通过运行这些测试用例来快速检查我的修改是否破坏了原有的功能。
通过这次实验,我深刻地认识到了单元测试的重要性。单元测试不仅可以帮助我们发现代码中的错误,还可以作为代码的文档,说明代码的预期行为。此外,单元测试还可以提高我们的开发效率,因为我们可以通过运行单元测试来快速检查我们的代码是否按预期工作,而不需要手动测试我们的代码。
总的来说,这次实验让我对C++的单元测试有了更深入的理解。我认识到了单元测试在软件开发中的重要性,并学会了如何编写和运行单元测试。我相信,这些知识和技能将对我未来的编程工作大有裨益。

5.博客地址
https://home.cnblogs.com/u/wangzhenghao1
6.Github地址
https://github.com/Wangzhenghao1

请在作业最后部分填写如下表格记录本次工作详细信息
项目 记录结果
日期 4.10
开始时间 4.8
结束时间 4.10
结束时间 4.10
编码行数 116
错误数量 0

posted @   Wangzhenghao1  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)
点击右上角即可分享
微信分享提示