Brief introduction
- Introduction to algorithms the fourth chapter introduces the use of divide and conquer method to find the largest sub-array problem, the basic idea is to divide an array into three parts, A[0:n/2],a[n/2+1:n],a[j:k] (of which 0<=j<=n/2,n/2+1<=k<=n), By recursively finding their maximum sub-array and then picking out the largest value, which is the maximum subarray value of the array, the algorithm has a time complexity of O (NLOGN)
- The white box test has five coverage criteria such as statement coverage, decision coverage, conditional coverage, decision/condition coverage, and conditional combination coverage.
- Environment: Ubuntu 16.04
- Language: C + +
- Test tool: Gtest (gtest frame construction Tutorial)
I. Issues
问题: 给定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。
--quoting "Baidu Encyclopedia"
You can refer to the introduction to the fourth chapter of the algorithm, or here or my GitHub, to see how the implementation, here is mainly to show you the function module and test the function module
Two. function function module
//max_array.cpp#include <iostream>#include "gtest/gtest.h"using namespaceStd/*** Function Function *@Author Stone*version1.0*///Get the maximum neutron arrayintFind_max_crossing_subarray (intA[],intLowintMidintHigh) {intsum =0;intLeft_sum, Right_sum;intMax_left, Max_right;intI, J; Left_sum = Right_sum =-1000;//makes the left and right sub-arrays and is infinitesimal, assuming that the array and not less than -1000 for(i = mid; I >= low; i--) {sum = sum + a[i];if(Sum > Left_sum) {left_sum = sum; Max_left = i; }} sum =0; for(j = Mid+1; J <= High; J + +) {sum = sum +a[j];if(Sum > Right_sum) {right_sum = sum; Max_right = j; }} low = Max_left; High = Max_right; sum = left_sum + right_sum;returnsum;}//Pass in the array, the low ordinal of the array, the high order number, returns the largest SubarrayintFind_maximum_subarray (intA[],intLowintHigh) {intLeft_sum, Right_sum, cross_sum;//low sequence number and high order number are the same if(Low = = high) {returnA[low]; }Else{intMid Mid = (low + high)/2; Left_sum = Find_maximum_subarray (A, low, mid);//Get maximum left sub-arrayRight_sum = Find_maximum_subarray (A, mid+1, high);//Get the maximum right sub-arrayCross_sum = Find_max_crossing_subarray (A, low, mid, high);//Get the maximum neutron array //Max Left sub-array is maximum sub-array if(Left_sum >= right_sum && left_sum >= cross_sum) {returnLeft_sum; }//MAX Right sub-array is maximum Subarray Else if(Right_sum >= left_sum && right_sum >= cross_sum) {returnRight_sum; }//MAX neutron array is maximum sub-array Else returnCross_sum; }}
Three. Testing
The test is performed by using the conditional combination overrides of the white-box test to perform enough test cases so that the various possible combinations of conditions in each decision appear at least once
1. function function
int FIND_MAXIMUM_SUBARRAY(int a[], int low, int high)
Flow chart
Through the flowchart, the conditional combination covers a total of 4 paths, respectively, AE,ABF,ABCG,ABCD, according to the definition of conditional combinations, there are 14 possible combinations, respectively:
1) Low = = High
2) Low! = High
3) left_sum >= right_sum,left_sum >= cross_sum
4) left_sum >= Right_sum,left_sum < cross_sum
5) Left_sum < right_sum,left_sum >= Cross_sum
6) Left_sum < Right_sum,left_sum < Cross_sum
7) right_sum >= left_sum,right_sum >= cross_sum
8) right_sum >= Left_sum,right_sum < cross_sum
9) Right_sum < left_sum,right_sum >= Cross_sum
Ten) Right_sum < Left_sum,right_sum < Cross_sum
One) cross_sum >= left_sum,cross_sum >= right_sum
Cross_sum >= Left_sum,cross_sum < right_sum
Cross_sum < left_sum,cross_sum >= Right_sum
Cross_sum < Left_sum,cross_sum < Right_sum
7 test cases are set up here to cover the 14 combinations of these conditions, as shown in the following table:
Test Cases |
Array |
Expected value |
Overlay Combo Number |
Execution Path |
Test Case 1 |
1 |
1 |
1 |
Ae |
Test Case 2 |
5,-3, 2,-3, 1 |
5 |
2,3,10,13 |
abf |
Test Case 3 |
-2, 11,-4, 13,-5,-2 |
20 |
2,6,8,11 |
Abcg |
Test Case 4 |
3,-4,-3,-7, 5 |
5 |
2,5,7,14 |
Abcd |
Test Case 5 |
-3, 2, 3,-2, 1 |
5 |
2,4,10,11 |
Abcg |
Test Case 6 |
-3,-2, 3,-4, 9 |
9 |
2,3,9,12 |
Abcg |
Test Case 7 |
5,-4,-2,-3,1 |
5 |
2,3,9,14 |
Abcd |
2. Test code
//Test moduleTEST (Max_arraytest0, MAX_ARRAYCASE0) {inta[0]; a[0] =1; Assert_eq (1, Find_maximum_subarray (A,0,1));} TEST (Max_arraytest1, max_arraycase1) {intb[5] = {5,-3,2,-3,1}; Assert_eq (5, Find_maximum_subarray (b,0,4));}//In the titleTEST (Max_arraytest2, Max_arraycase2) {intc[6] = {-2, One,-4, -,-5,-2}; Assert_eq ( -, Find_maximum_subarray (c,0,5));} TEST (Max_arraytest3, MAX_ARRAYCASE3) {intd[5] = {3,-4,-3,-1,Ten}; Assert_eq (Ten, Find_maximum_subarray (D,0,4));} TEST (Max_arraytest4, Max_arraycase4) {inte[5] = {-3,2,3,-2,1}; Assert_eq (5, Find_maximum_subarray (E,0,4));} TEST (MAX_ARRAYTEST5, max_arraycase5) {intf[5] = {-3,-2,3,-4,9}; Assert_eq (9, Find_maximum_subarray (F,0,4));} TEST (Max_arraytest6, Max_arraycase6) {intf[5] = {5,-4,-2,-3,1}; Assert_eq (5, Find_maximum_subarray (F,0,4));}intMainintargcChar* argv[]) {testing::initgoogletest (&ARGC, argv);returnRun_all_tests ();}
In the terminal, enter in sequence:
g++ -o max_array.o -c max_array.cpp -I./include
g++ -o test *.o -I./include -L./lib -lgtest -lpthread
./test
All green, test pass!
Four. Summary
At the beginning of the test, misunderstood the definition of conditional combination coverage, has been tangled in how to test the recursion, and then understand that conditional combination coverage is required to make each of the conditions in the decision of the various possible combinations at least once , so that directly to test the decision-making is OK, therefore, It's important to understand what unit testing is, not to say that code needs to be tested, and that it's futile.
Maximum sub-array summation and conditional combination overlay test