Skip to content

Commit 0b6a493

Browse files
committed
第四章通过测试
1 parent ebfa857 commit 0b6a493

10 files changed

+174
-43
lines changed

.gitignore

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,22 @@
2828
*.out
2929
*.app
3030

31+
## Add By JunGor
32+
3133
# Stackdump
3234
*.stackdump
3335

34-
# Dependency ifles
36+
# Dependency files
3537
*.d
38+
39+
# Bin files
40+
main
41+
test
42+
43+
# Tags files
44+
tags
45+
46+
# YCM Config files
47+
compile_commands.json
48+
.ycm_extra_conf.py
49+
.color_coded

Makefile

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
1+
ALLFILES = $(subst ./,,$(wildcard ./chap*/*.[ch]) $(wildcard ./*.[ch]))
12
ALLSRCS = utils.c $(subst ./,,$(wildcard ./chap*/*.c))
23
TESTSRCS = $(subst ./,,$(wildcard ./chap*/test*.c))
34
SRCS = $(filter-out $(TESTSRCS), $(ALLSRCS))
45
ALLOBJS = $(patsubst %.c, %.o, $(ALLSRCS))
56
OBJS = $(patsubst %.c, %.o, $(SRCS))
67

78
CC = gcc
8-
CFLAGS = -Wall -g
9+
CFLAGS = -Wall -g -std=gnu99
910
INCLUDEFLAGS =
1011
LDFLAGS = -lcunit
1112
TARGET = main
1213
TEST = test
1314

14-
.PHONY:run
15-
run: all
16-
./$(TEST)
17-
1815
.PHONY:all
19-
all: $(TARGET) $(TEST)
16+
all: $(TARGET) $(TEST) tags
2017

2118
$(TARGET): $(addsuffix .o, $(TARGET)) $(OBJS)
22-
$(CC) -o $@ $^ $(LDFLAGS)
19+
@$(CC) -o $@ $^ $(LDFLAGS)
2320

2421
$(TEST): $(addsuffix .o, $(TEST)) $(ALLOBJS)
25-
$(CC) -o $@ $^ $(LDFLAGS)
22+
@$(CC) -o $@ $^ $(LDFLAGS)
23+
24+
tags: $(ALLFILES)
25+
@ctags -R .
2626

2727
%.o:%.c
28-
$(CC) -o $@ -c $< $(CFLAGS) $(INCLUDEFLAGS)
28+
@$(CC) -o $@ -c $< $(CFLAGS) $(INCLUDEFLAGS)
2929

3030
%.d:%.c
3131
@set -e; rm -f $@; $(CC) -MM $< $(INCLUDEFLAGS) > $@.$$$$; \
@@ -36,17 +36,23 @@ $(TEST): $(addsuffix .o, $(TEST)) $(ALLOBJS)
3636

3737
.PHONY:clean
3838
clean:
39-
rm -f $(TARGET) $(OBJS) **/*.d **/*.d.*
39+
@rm -f $(TARGET) $(OBJS) **/*.d **/*.d.*
4040

4141
.PHONY:debug
4242
debug:
43-
gdb $(TARGET)
43+
@gdb $(TEST)
4444

4545
.PHONY:dump
4646
dump:
47-
less $(TARGET).exe.stackdump
47+
@less $(TARGET).exe.stackdump
48+
49+
.PHONY:run
50+
run: all
51+
@./$(TEST)
52+
4853
.PHONY:var
4954
var:
55+
@echo ALLFILES: $(ALLFILES)
5056
@echo ALLSRCS: $(ALLSRCS)
5157
@echo TESTSRCS: $(TESTSRCS)
5258
@echo SRCS: $(SRCS)

chap02/test_insertion_sort.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ static void test_insertion_sort() {
1717
}
1818

1919
CU_ErrorCode add_test_insertion_sort() {
20-
CU_pSuite pSuite = CU_add_suite("SuitInsertionSort", NULL, NULL);
20+
CU_pSuite pSuite = CU_add_suite("insertion_sort", NULL, NULL);
2121
CHECK_CU_GLOBAL();
2222
CU_ADD_TEST(pSuite, test_insertion_sort);
2323
CHECK_CU_GLOBAL();

chap02/test_merge_sort.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
1+
#include "merge_sort.h"
12
#include "test_merge_sort.h"
23
#include "../utils.h"
4+
#include <CUnit/CUnit.h>
35
#include <stdlib.h>
46

5-
CU_ErrorCode add
7+
static void test_merge_sort() {
8+
int len = 100;
9+
int nums[len];
10+
for (int i = 0; i < len; i++) {
11+
nums[i] = rand();
12+
}
13+
merge_sort(nums, len);
14+
for (int i = 1; i < len; i++) {
15+
CU_ASSERT(nums[i-1] <= nums[i]);
16+
}
17+
}
18+
19+
CU_ErrorCode add_test_merge_sort() {
20+
CU_pSuite pSuite = CU_add_suite("merge_sort", NULL, NULL);
21+
CHECK_CU_GLOBAL();
22+
CU_ADD_TEST(pSuite, test_merge_sort);
23+
CHECK_CU_GLOBAL();
24+
return CUE_SUCCESS;
25+
}

chap04/maximum_subarray.c

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,68 @@
11
/**
22
* maximum_subarray.cpp
33
* 最大子数组
4+
*/
5+
#include <limits.h>
6+
#include <stdio.h>
7+
#include "maximum_subarray.h"
8+
#include "../utils.h"
9+
10+
static MSA_slt_t maximum_subarray_daq(int nums[], int begin, int end);
11+
static MSA_slt_t maximum_subarray_linear(int nums[], int begin, int end);
12+
13+
/**
14+
* 解法1:分治法
415
* 分:均分成两个子数组。最大子数组只能是以下三种位置:
516
* 1. 完全在左子数组。此时它也是左子数组的最大子数组
617
* 2. 完全在右子数组。此时它也是左子数组的最大子数组
718
* 3. 一部分在左,一部分在右
819
* 此思路不是最优算法,有线性时间算法。
920
*/
10-
#include <limits.h>
11-
#include <stdio.h>
12-
#include "maximum_subarray.h"
13-
14-
subarr maximum_subarray(int nums[], int begin, int end) {
21+
MSA_slt_t maximum_subarray_daq(int nums[], int begin, int end) {
1522
int len = end - begin;
16-
subarr sa;
23+
MSA_slt_t sa;
1724
if (len == 1) {
1825
sa.left = sa.right = begin;
19-
sa.sum = nums[0];
26+
sa.sum = nums[begin];
2027
return sa;
2128
}
2229
int mid = begin + len/2;
2330
// 左右子数组的最大子数组
24-
subarr lsa = maximum_subarray(nums, begin, mid);
25-
subarr rsa = maximum_subarray(nums, mid, end);
31+
MSA_slt_t lsa = maximum_subarray_daq(nums, begin, mid);
32+
MSA_slt_t rsa = maximum_subarray_daq(nums, mid, end);
2633
// 跨越mid的最大子数组
2734
int maxsum = INT_MIN;
2835
int suml = 0;
29-
int maxi, sum = 0;
36+
int sum = 0;
3037
int maxil = mid-1;
31-
for (int i = mid-1; i >= 0; i--) {
32-
suml += nums[begin+i];
38+
for (int i = mid-1; i >= begin; i--) {
39+
suml += nums[i];
3340
if (suml > maxsum) {
3441
maxsum = suml;
35-
maxil = begin+i;
42+
maxil = i;
3643
}
3744
}
3845
sum += maxsum;
3946
maxsum = INT_MIN;
4047
int sumr = 0;
4148
int maxir = mid;
42-
for (int i = mid; i < len; i++) {
43-
sumr += nums[begin+i];
49+
for (int i = mid; i < end; i++) {
50+
sumr += nums[i];
4451
if (sumr > maxsum) {
4552
maxsum = sumr;
46-
maxir = begin+i;
53+
maxir = i;
4754
}
4855
}
4956
sum += maxsum;
57+
// 选择三种分类中的最优解
5058
if (lsa.sum > rsa.sum) {
51-
sa = lsa;
59+
sa.left = lsa.left;
60+
sa.right = lsa.right;
61+
sa.sum = lsa.sum;
5262
} else {
53-
sa = rsa;
63+
sa.left = rsa.left;
64+
sa.right = rsa.right;
65+
sa.sum = rsa.sum;
5466
}
5567
if (sum > sa.sum) {
5668
sa.sum = sum;
@@ -60,3 +72,32 @@ subarr maximum_subarray(int nums[], int begin, int end) {
6072
// printf("%d %d %d\n", suml, sumr, sum);
6173
return sa;
6274
}
75+
76+
77+
MSA_slt_t maximum_subarray_linear(int nums[], int begin, int end) {
78+
MSA_slt_t slt = {begin, begin, nums[begin]};
79+
int cur = nums[begin];
80+
int left = begin;
81+
for (int i = begin+1; i < end; i++) {
82+
if (cur <= 0) {
83+
cur = nums[i];
84+
left = i;
85+
} else {
86+
cur += nums[i];
87+
}
88+
if (cur > slt.sum) {
89+
slt.left = left;
90+
slt.right = i;
91+
slt.sum = cur;
92+
}
93+
}
94+
return slt;
95+
}
96+
97+
MSA_slt_t maximum_subarray(int nums[], int begin, int end, MSA_policy_t p) {
98+
if (p == MSA_PLC_DAQ) {
99+
return maximum_subarray_daq(nums, begin, end);
100+
} else {
101+
return maximum_subarray_linear(nums, begin, end);
102+
}
103+
}

chap04/maximum_subarray.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
#ifndef MAXIMUM_SUBARRAY_H
22
#define MAXIMUM_SUBARRAY_H
33

4-
struct subarr {
5-
int left;
6-
int right;
7-
int sum;
4+
struct MSA_slt_s {
5+
int left; // 最大子数组的左端点(闭)
6+
int right; // 最大子数组的右端点(闭)
7+
int sum; // 最大子数组的和
88
};
99

10-
typedef struct subarr subarr;
10+
typedef struct MSA_slt_s MSA_slt_t;
1111

12-
subarr maximum_subarray(int nums[], int begin, int end);
12+
enum MSA_policy_e {
13+
MSA_PLC_DAQ, // 分治法
14+
MSA_PLC_LINEAR // 线性时间算法
15+
};
16+
17+
typedef enum MSA_policy_e MSA_policy_t;
18+
19+
MSA_slt_t maximum_subarray(int nums[], int begin, int end, MSA_policy_t p);
1320

1421
#endif

chap04/test_maximum_subarray.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include "test_maximum_subarray.h"
2+
#include "maximum_subarray.h"
3+
#include "../utils.h"
4+
#include <CUnit/CUnit.h>
5+
#include <stdlib.h>
6+
7+
static void test_maximum_subarray() {
8+
int nums[] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
9+
MSA_slt_t slt = maximum_subarray(nums, 0, sizeof(nums)/sizeof(int), MSA_PLC_DAQ);
10+
CU_ASSERT_EQUAL(slt.left, 7);
11+
CU_ASSERT_EQUAL(slt.right, 10);
12+
CU_ASSERT_EQUAL(slt.sum, 43);
13+
slt = maximum_subarray(nums, 0, sizeof(nums)/sizeof(int), MSA_PLC_LINEAR);
14+
CU_ASSERT_EQUAL(slt.left, 7);
15+
CU_ASSERT_EQUAL(slt.right, 10);
16+
CU_ASSERT_EQUAL(slt.sum, 43);
17+
int nums2[] = {1, 2, -3, 1};
18+
slt = maximum_subarray(nums2, 0, sizeof(nums2)/sizeof(int), MSA_PLC_LINEAR);
19+
printf("%d, %d, %d\n", slt.left, slt.right, slt.sum);
20+
CU_ASSERT_EQUAL(slt.left, 0);
21+
CU_ASSERT_EQUAL(slt.right, 1);
22+
CU_ASSERT_EQUAL(slt.sum, 3);
23+
}
24+
25+
CU_ErrorCode add_test_maximum_subarray() {
26+
CU_pSuite pSuite = CU_add_suite("maximum_subarray", NULL, NULL);
27+
CHECK_CU_GLOBAL();
28+
CU_ADD_TEST(pSuite, test_maximum_subarray);
29+
CHECK_CU_GLOBAL();
30+
return CUE_SUCCESS;
31+
}

chap04/test_maximum_subarray.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef TEST_MAXIMUM_SUBARRAY_H
2+
#define TEST_MAXIMUM_SUBARRAY_H
3+
4+
#include <CUnit/CUnit.h>
5+
6+
CU_ErrorCode add_test_maximum_subarray();
7+
8+
#endif

chap15/test_optimal_binary_search_tree.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "optimal_binary_search_tree.h"
22
#include "../utils.h"
33
#include <CUnit/CUnit.h>
4-
#include <CUnit/console.h>
4+
#include <CUnit/Console.h>
55
#include <stdio.h>
66

77
static int InitSuite() {
@@ -28,7 +28,7 @@ CU_ErrorCode add_test_obst() {
2828
* 2. Suite名字 : testSuite
2929
* 3. InitSuite EndSuite:分别是测试单元初始和释放函数,如不需要则NULL传递
3030
****************/
31-
pSuite = CU_add_suite("TestOBST", InitSuite, EndSuite);
31+
pSuite = CU_add_suite("optimal_bst", InitSuite, EndSuite);
3232
CHECK_CU_GLOBAL();
3333

3434
/***************

test.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
#include "chap02/test_insertion_sort.h"
2+
#include "chap02/test_merge_sort.h"
3+
#include "chap04/test_maximum_subarray.h"
24
#include "chap15/test_optimal_binary_search_tree.h"
35
#include "utils.h"
46
#include <stdio.h>
57
#include <stdlib.h>
68
#include <time.h>
7-
#include <CUnit/console.h>
9+
#include <CUnit/Console.h>
810

911
int main() {
1012
srand(time(NULL));
@@ -20,8 +22,10 @@ int main() {
2022
//assert(!CU_is_test_running());
2123

2224
//注册各个suite
23-
CHECK_CU_RETURN(add_test_obst());
2425
CHECK_CU_RETURN(add_test_insertion_sort());
26+
CHECK_CU_RETURN(add_test_merge_sort());
27+
CHECK_CU_RETURN(add_test_maximum_subarray());
28+
CHECK_CU_RETURN(add_test_obst());
2529

2630
//使用console控制交互界面的函数入口
2731
CU_console_run_tests();

0 commit comments

Comments
 (0)