本次作业简介:
问 | 答 |
---|---|
这个作业要求在哪里 | 作业三的链接见:第三周作业 |
我在这个课程的目标是 | 编程能力和思维灵活性的提高;代码量和编程实战能力的提升 |
此作业在哪个具体方面帮我实现目标 | 编程能力的提高 |
其他参考文献 | 参考1:求最大子数组 参考2:VS C++单元测试的实现1 参考:3:VS C++单元测试的实现2 参考4:C++的文件操作 |
作业正文 | 作业三 |
正文
单元测试
题目要求
用类/函数来实现
- 需求:希望返回 3 种信息
最大子数组的和
最大子数组开始的下标
最大子数组结束的下标 - 从文本文件中读输入的数据,熟悉文件操作, 文件有两种数据
第一个数字:这次测试中有多少个数据, 数字后面是冒号。
后续数字:每个数据的值,用逗号隔开
比如
文件内容:
17: -32, -10, 33, -23, 32, -12, 41, -12, 1, 3, 5, -98, 70, -21, 10, -9, 61
输出
sum = 71
问题分析
最大连续子数组的定义为:一个整数数组中的元素有正有负,在该数组中找出一 个连续子数组,要求该连续子数组中各元素的和最大,这个连续子数组便被称作最大连续子数组。查阅相关博客和网页资料,了解到求解最大连续子数组的常用方法有:1.暴力求解法;2.分治法;3.贪心算法。它们的复杂度分别为:1.O(n^2);2.O(nlog(n));3.O(n)。本次作业采用的就是分治法来求解,后再通过3个单元测试验证程序的正确性。
因为本次作业使用的编程语言是C++,先前VS2010等版本很难实现C++的单元测试,故下载了vs2017版本。有三个程序文件:详情见文末的代码附录,同时也将其托管到了远程仓库中。
码云上仓库的链接地址为:仓库、单元测试
函数测试结果分析
单元测试添加后:
要想成功进行单元测试,首先需要将函数的编写正确,即能通过编译,否则运行单与测试时会显示单元测试未运行。如果函数编写没有问题,但是单元测试仍就无法运行,根据参考的相关博客,需要在测试项目右击,点击的属性->清单工具->输入->附加依赖项->编辑,之后将.obj文件附加进去。(详细过程可以参考文章开头列出的博文:参考2和参考3)
附加过程:
添加成功后,测试文件成功运行,如下:
单元测试运行成功:
将程序push到远程仓库中
博客作业
回顾本专业前两年半的学习经历,学习了很多与计算机和编程相关的课程。第一年接触了基础的一些课程:大学计算机基础(主要适合MS Office相关)、C++(与编程的初次接触,学习了一些较为基础的编程知识);第二年学习了:数据结构(对编程和算法的认识得到了进一步的提高,代码的编写量也有相应地增加,对编程的思想有了更进一步的学习)、Java(这是接触的第二个语言,在NetBeans进行编程时,十分方便,比C++更为方便简单些);第三年:MATLAB(首先是通过数值分析的学习,对MATLAB进行了一些使用,后用通过MATLAB与科学计算这门课程进行了系统的学习,它是一款强大的数学软件,使用方便,功能很强大)、数据库和操作系统(通过这两门课程的学习,对数据库以及计算机操作系统的相关理论有了一定的学习了解,能够通过计算机终端进行操作)、ASP.Net(通过这门课程的学习,对网页设计以及一些控件管理、前台操作与后台数据库的链接进行了初步学习)。在学习C++,数据结构、数据库和ASP.Net时都做了相应的课程设计,大部分是通过团队合作进行完成的。
本人目前会C++,MATLAB、JAVA和ASP.Net的一些基本操作。对C++和MATLAB较为熟悉些,对已有程序的阅读,首先是看相关的说明文件和注释,如果代码的这两部分不够清晰,则先看看主函数的实现过程,根据主函数阅读其使用到的函数。关于编程的技能方面,后面需要加强的主要是
预习
代码的规范和复审
这一部分主要是阐述了代码的规范的重要性,一个重要的原则就是:简明,易读,无二义性。一个简明易读的代码,不仅能够提高个人对代码的检查分析,也有利于后期的代码复审和多人合作。
代码复审主要目的是:1.找出代码错误;2.发现逻辑错误(程序可以编译通过,但是代码的逻辑是错的);3.发现算法错误(比如使用的算法不够优化等);4.发现潜在的错误和回归性错误(当前的修改是否会导致以前修复的缺陷又重新出现);5.发现可能改进的地方;6.教育(互相教育)开发人员,传授经验,让更多的成员熟悉项目各部分的代码,同时熟悉和应用领域相关的实际知识。其一般形式有:自我复审、同伴复审、团队复审。其中最基本的就是同伴复审,团队复审是最严格的。
结对编程
其实刚开始,个人也觉得结对编程会让人很不适应,通读了文章再想想,如果两个人能够很好的配合的话,那结对编程的确能够提高编程的效率,避免一些错误,正如讲义中所说结对编程的两个人就像驾驶员和领航员的作用,如果配合得当,两个人会互相影响提高,能够得到更高的投入产出比。在团队合作中, 处于平等地位的团队成员一般是通过 “影响 + 反馈” 的方式来影响同伴
代码附录
//分治法实现查找最大连续子数组的.cpp文件:Array_Cal.cpp
// Array_Cal.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
//用类/函数来实现:
//一、需求:希望返回 3 种信息: 最大子数组的和,最大子数组开始的下标,最大子数组结束的下标
//二、从文本文件中读输入的数据,熟悉文件操作, 文件有两种数据。第一个数字:这次测试中有多少个数据, 数字后面是冒号。后续数字: 每个数据的值,用逗号隔开
#include<iostream>
#include"Array_Cal.h"
#include<cstdlib>
#define N 1000
#define Max 5000
using namespace std;
//分治法
R Max_Sum(int A[], int low, int mid, int high)
{
R b;
int Max_L = mid;//左边最大值位置
int Max_SL = -Max;//左边最大和
int SL = 0;
//左边
for (int i = mid;i >= low;i--)
{
SL += A[i];
if (SL > Max_SL)
{
Max_SL = SL;
Max_L = i;
}
}
//右边
int Max_R = mid + 1;//右边最大值位置
int Max_SR = -Max;//右边最大和
int SR = 0;
for (int i = mid+1;i <= high;i++)
{
SR += A[i];
if (SR > Max_SR)
{
Max_SR = SR;
Max_R = i;
}
}
b.l = Max_L;
b.r = Max_R;
b.s = Max_SR + Max_SL;
return b;
}
int main()
{
int a[] = {-1,1,2,6,5,4,3};
R t=Max_subArray(a,0,6);
cout << t.l<<" "<<t.r<<" "<<t.s;
}
//分治法实现查找最大数组
R Max_subArray(int A[], int start, int end)//A表示所分析的数组
{
R b,t1,t2,t3;
if (start == end)
{
b.l = start;
b.r = end;
b.s = A[start];
return b;
}
else
{
int mid = (start + end) / 2;
t1 = Max_subArray(A, start, mid);
t2 = Max_subArray(A, mid + 1, end);
t3 = Max_Sum(A, start, mid, end);
}
if (t1.s < t2.s || t1.s < t3.s)
{
if (t2.s < t3.s) return t3;
else return t2;
}
else return t1;
}
//头文件Array_Cal.h
#pragma once
struct R//结构体,返回最大子数组的左侧下标/右侧下标/元素和
{
int l, r, s;
};
R Max_subArray(int A[], int start, int end);
//测试文件UnitTest1.cpp
#include "pch.h"
#include "CppUnitTest.h"
#include "..Array_CalArray_Cal.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace UnitTest1
{
TEST_CLASS(UnitTest1)
{
public:
TEST_METHOD(TestMethod1)
{
int a[] = { 4,3,2,1,5 };
R t=Max_subArray(a,0,5);
Assert::AreEqual(t.l,0);
Assert::AreEqual(t.r,4);
Assert::AreEqual(t.s,15);
}
TEST_METHOD(TestMethod2)
{
int a[] = { -4,-2,-3,-7 };
R t = Max_subArray(a, 0, 3);
Assert::AreEqual(t.l, 1);
Assert::AreEqual(t.r, 1);
Assert::AreEqual(t.s, -2);
}
TEST_METHOD(TestMethod3)
{
int a[] = { -5,5,-3,2,-1,0,4 };
R t = Max_subArray(a, 0, 6);
Assert::AreEqual(t.l, 1);
Assert::AreEqual(t.r, 6);
Assert::AreEqual(t.s,7);
}
};
}