Go语言归并排序算法实现TDD实践报告

这篇博客介绍了在Go语言中实现归并排序的TDD实践过程。首先,作者进行迭代章节练习,修改测试代码以指定字符重复次数,并添加ExampleRepeat来完善函数文档。接着,展示了如何编写测试用例并实现归并排序算法,确保其通过测试。最后,进行了基准测试以评估算法性能,并提供了代码链接和参考资料。
摘要由CSDN通过智能技术生成

服务计算Homework02

迭代章节练习
  1. 修改测试代码,以便调用者可以指定字符重复的次数,然后修复代码
    • 修改测试代码如下

      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执行单个测试文件提示未定义问题

  2. 写一个 ExampleRepeat 来完善你的函数文档
    • 整数这一章节所示,在repeat_test.go中添加如下所示示例
      func ExampleRepeat() {
      	result := Repeat("a", 6)
      	fmt.Println(result)
      	// Ouput: aaaaaa
      }
      
      
    • 结果如下图
      在这里插入图片描述

注意上述代码中最后一行// Ouput: aaaaaaaaaa

  • 如果没有这一行代码或者Output拼写错误(不区分大小写)则不会RUN ExampleRepeat
  • 如果Output后的结果与应得结果不符则会FAIL,如下图
    在这里插入图片描述
  1. 看一下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流程

  1. 写一个测试用例并运行测试

    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}
    }
    

    结果如下
    在这里插入图片描述

  2. 实现能通过测试的程序并测试

    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函数注释,运行测试结果如下
    在这里插入图片描述

  3. 重构、修改代码

    由于mergeSort算法较为常用且简单,已经形成一种相对固定的套路,基本没有需要重构和修改的地方,在本文中仅作注释以实现这个步骤

  4. 基准测试

    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.gomergeSort_test.go放在同一个新开的文件夹中(该文件夹不要有其他.go文件)
    • mergeSort.gomergeSort_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详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值