服务计算Homework02
迭代章节练习
- 修改测试代码,以便调用者可以指定字符重复的次数,然后修复代码
-
修改测试代码如下
package iteration import "testing" func TestRepeat(t *testing.T) { repeated := Repeat("a", 10) expected := "aaaaaaaaaa" if repeated != expected { t.Errorf("expected '%q' but got '%q'", expected, repeated) } }
-
修复代码如下
package iteration func Repeat(character string, count int) string { var repeated string for i := 0; i < count; i++ { repeated = repeated + character } return repeated }
-
结果如下
注意test测试单个文件需要执行命令时加入这个测试文件需要引用的源码文件,参考博客解决Go test执行单个测试文件提示未定义问题
-
- 写一个 ExampleRepeat 来完善你的函数文档
- 如
整数
这一章节所示,在repeat_test.go
中添加如下所示示例func ExampleRepeat() { result := Repeat("a", 6) fmt.Println(result) // Ouput: aaaaaa }
- 结果如下图
- 如
注意上述代码中最后一行
// Ouput: aaaaaaaaaa
,
- 如果没有这一行代码或者Output拼写错误(不区分大小写)则不会
RUN ExampleRepeat
- 如果Output后的结果与应得结果不符则会FAIL,如下图
-
看一下strings包(网站上的连接需要连接外网,这里提供的是中文版网站)。找到你认为可能有用的函数,并对它们编写一些测试。投入时间学习标准库会慢慢得到回报。
func EqualFold(s, t string) bool
: 判断两个utf-8编码字符串(将unicode大写、小写、标题三种格式字符视为相同)是否相同。func HasPrefix(s, prefix string) bool
: 判断s是否有前缀字符串prefix。func Count(s, sep string) int
: 返回字符串s中有几个不重复的sep子串。
测试代码及结果如下
package iteration import ( "strings" "testing" ) func TestEqualFold(t *testing.T) { result := strings.EqualFold("GO", "go") expected := true if result != expected { t.Errorf("expected '%t' but got '%t'", expected, result) } } func TestHasPrefix(t *testing.T) { result := strings.HasPrefix("food", "foo") expected := true if result != expected { t.Errorf("expected '%t' but got '%t'", expected, result) } } func TestCount(t *testing.T) { result := strings.Count("food", "o") expected := 2 if result != expected { t.Errorf("expected '%d' but got '%d'", expected, result) } }
归并排序的算法实现
归并排序(Merge Sort)
是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
TDD流程
-
写一个测试用例并运行测试
package main import "testing" var arr = []int{1, 3, 1, 6, 7, 9, 2, 4, 3, 1, 7} func TestMergeSort(t *testing.T) { result := mergeSort(arr) expected := []int{1, 1, 1, 2, 3, 3, 4, 6, 7, 7, 9} flag := true for i := 0; i < len(arr); i++ { if result[i] != expected[i] { flag = false } } if flag == false { t.Errorf("expected ") for i := 0; i < len(arr); i++ { t.Errorf("%d\t", expected[i]) } t.Errorf("but got") for i := 0; i < len(arr); i++ { t.Errorf("%d\t", result[i]) } } }
为了运行测试,需要先添加一个空的
mergeSort
函数(根据TDD的步骤等下再实现)package main func mergeSort(arr []int) []int { return []int{1, 3, 1, 6, 7, 9, 2, 4, 3, 1, 7} }
结果如下
-
实现能通过测试的程序并测试
package main func mergeSort(arr []int) []int { if len(arr) < 2 { return arr } i := len(arr) / 2 left := mergeSort(arr[0:i]) right := mergeSort(arr[i:]) result := merge(left, right) return result } func merge(left, right []int) []int { result := make([]int, 0) m, n := 0, 0 // left和right的index位置 l, r := len(left), len(right) for m < l && n < r { if left[m] > right[n] { result = append(result, right[n]) n++ continue } result = append(result, left[m]) m++ } result = append(result, right[n:]...) result = append(result, left[m:]...) return result } func main() { arr := []int{1, 3, 1, 6, 7, 9, 2, 4, 3, 1, 7} result := mergeSort(arr) fmt.Println(result) }
先用main函数检测输出,结果正确如下
然后将main函数注释,运行测试结果如下
-
重构、修改代码
由于
mergeSort
算法较为常用且简单,已经形成一种相对固定的套路,基本没有需要重构和修改的地方,在本文中仅作注释以实现这个步骤 -
基准测试
在
mergeSort_test.go
的基础上添加如下代码func BenchmarkMergesort(b *testing.B) { for i := 0; i < b.N; i++ { var arrt = []int{1, 3, 1, 6, 7, 9, 2, 4, 3, 1, 7} mergeSort(arrt) } }
结果如下图
- 注意将
mergeSort.go
和mergeSort_test.go
放在同一个新开的文件夹中(该文件夹不要有其他.go文件) mergeSort.go
和mergeSort_test.go
都只包含test这个package,否则会出现类似报错found packages main (mergeSort.go) and test (mergeSort_test.go) in D:\goworks\src\newset
(就是找到两个package,然后不能执行)
- 注意将
参考资料
深度解读 - TDD
GO语言中文文档
往届博客参考
GO语言benchmark
GO语言benchmark详解