程序设计
目标:开发一个排序算法的比较程序,从命令行指定输入的数据文件和输出的数据文件,并指定对应的排序算法。该程序的用法如下:
USAGE:sorter -i -o -a <qsort | bubblesort>
程序结构
[wangzheng@wangzheng-centos sorter]$ tree
.
└── src
├── algorithm
│ ├── bubblesort 冒泡排序
│ │ ├── bubblesort.go
│ │ └── bubblesort_test.go
│ └── qsort 快速排序
│ ├── qsort.go
│ └── qsort_test.go
└── sorter 主程序
├── sorter
└── sorter.go
5 directories, 6 files
[wangzheng@wangzheng-centos sorter]$
程序实现
算法实现
冒泡排序
源文件:bubblesort.go
[wangzheng@wangzheng-centos src]$ cat algorithm/bubblesort/bubblesort.go
package bubblesort
func Bubblesort(values []int) {
flag := true
for i:= 0; i < len(values) - 1; i++ {
flag = true
for j := 0; j < len(values) - i - 1; j++ {
if values[j] > values[j + 1] {
values[j], values[j + 1] = values[j + 1], values[j]
flag = false
}
}
if flag {
break
}
}
}
[wangzheng@wangzheng-centos src]$
单元测试:bubblesort_test.go
[wangzheng@wangzheng-centos src]$ cat algorithm/bubblesort/bubblesort_test.go
package bubblesort
import "testing"
func TestBubblesort1(t *testing.T) {
values := []int{5, 4, 3, 2, 1}
Bubblesort(values)
if values[0] != 1 || values[1] != 2 || values[2] != 3 || values[3] != 4 ||
values[4] != 5 {
t.Error("Bubblesort() failed. Got", values, "Expected 1 2 3 4 5")
}
}
func TestBubblesort2(t *testing.T) {
values := []int{5, 5, 3, 2, 1}
Bubblesort(values)
if values[0] != 1 || values[1] != 2 || values[2] != 3 || values[3] != 5 ||
values[4] != 5 {
t.Error("Bubblesort() failed. Got", values, "Expected 1 2 3 5 5")
}
}
func TestBubblesort3(t *testing.T) {
values := []int{5}
Bubblesort(values)
if values[0] != 5 {
t.Error("Bubblesort() failed. Got", values, "Expected 5")
}
}
[wangzheng@wangzheng-centos src]$
快速排序
源文件:qsort.go
[wangzheng@wangzheng-centos src]$ cat algorithm/qsort/qsort.go
package qsort
func quickSort(values []int, left, right int) {
temp := values[left]
p := left
i, j := left, right
for i <= j {
for j >= p && values[j] >= temp {
j--
}
if j >= p {
values[p] = values[j]
p = j
}
if values[i] <= temp && i <= p {
i++
}
if i <= p {
values[p] = values[i]
p = i
}
}
values[p] = temp
if p - left > 1 {
quickSort(values, left, p - 1)
}
if right - p > 1 {
quickSort(values, p + 1, right)
}
}
func QuickSort(values []int) {
quickSort(values, 0, len(values) - 1)
}
[wangzheng@wangzheng-centos src]$
单元测试:qsort_test.go
[wangzheng@wangzheng-centos src]$ cat algorithm/qsort/qsort_test.go
package qsort
import "testing"
func TestQuickSort1(t *testing.T) {
values := []int{5, 4, 3, 2, 1}
QuickSort(values)
if values[0] != 1 || values[1] != 2 || values[2] != 3 || values[3] != 4 ||
values[4] != 5 {
t.Error("QuickSort() failed. Got", values, "Expected 1 2 3 4 5")
}
}
func TestQuickSort2(t *testing.T) {
values := []int{5, 5, 3, 2, 1}
QuickSort(values)
if values[0] != 1 || values[1] != 2 || values[2] != 3 || values[3] != 5 ||
values[4] != 5 {
t.Error("QuickSort() failed. Got", values, "Expected 1 2 3 5 5")
}
}
func TestQuickSort3(t *testing.T) {
values := []int{5}
QuickSort(values)
if values[0] != 5 {
t.Error("QuickSort() failed. Got", values, "Expected 5")
}
}
[wangzheng@wangzheng-centos src]$
主程序
主程序:sorter.go
[wangzheng@wangzheng-centos src]$ cat sorter/sorter.go
package main
import "bufio"
import "flag"
import "fmt"
import "io"
import "os"
import "strconv"
import "time"
import "algorithm/bubblesort"
import "algorithm/qsort"
var infile *string = flag.String("i", "infile", "File contains values for sorting")
var outfile *string = flag.String("o", "outfile", "File to receive sorted values")
var algorithm *string = flag.String("a", "qsort", "Sort algorithm")
func readValues(infile string) (values []int, err error) {
file, err := os.Open(infile)
if err != nil {
fmt.Println("Failed to open the input file ", infile)
return
}
defer file.Close()
br := bufio.NewReader(file)
values = make([]int, 0)
for {
line, isPrefix, err1 := br.ReadLine()
if err1 != nil {
if err1 != io.EOF {
err = err1
}
break
}
if isPrefix {
fmt.Println("A too long line, seems unexpected.")
return
}
str := string(line)
value, err1 := strconv.Atoi(str)
if err1 != nil {
err = err1
return
}
values = append(values, value)
}
return
}
func writeValues(values []int, outfile string) error {
file, err := os.Create(outfile)
if err != nil {
fmt.Println("Failed to create the output file ", outfile)
return err
}
defer file.Close()
for _, value := range values {
str := strconv.Itoa(value)
file.WriteString(str + "\n")
}
return nil
}
func main() {
flag.Parse()
if infile != nil {
fmt.Println("infile =", *infile, "outfile =", *outfile, "algorithm =", *algorithm)
}
values, err := readValues(*infile)
if err == nil {
t1 := time.Now()
switch *algorithm {
case "qsort":
qsort.QuickSort(values)
case "bubblesort":
bubblesort.Bubblesort(values)
default:
fmt.Println("Sorting algorithm", *algorithm, "is either unknow or unsupported.")
}
t2 := time.Now()
fmt.Println("The sorting process costs", t2.Sub(t1), "to complete.")
writeValues(values, *outfile)
} else {
fmt.Println(err)
}
}
构建程序
[wangzheng@wangzheng-centos sorter]$ echo $GOPATH
/home/wangzheng/sorter
[wangzheng@wangzheng-centos src]$ pwd
/home/wangzheng/sorter/src
[wangzheng@wangzheng-centos src]$ ls
algorithm sorter
[wangzheng@wangzheng-centos src]$ go build algorithm/qsort/
[wangzheng@wangzheng-centos src]$ go build algorithm/bubblesort/
[wangzheng@wangzheng-centos src]$ go test algorithm/qsort/
ok algorithm/qsort 0.062s
[wangzheng@wangzheng-centos src]$ go test algorithm/bubblesort/
ok algorithm/bubblesort 0.067s
[wangzheng@wangzheng-centos src]$ go install algorithm/qsort/
[wangzheng@wangzheng-centos src]$ go install algorithm/bubblesort/
[wangzheng@wangzheng-centos src]$ cd sorter/
[wangzheng@wangzheng-centos sorter]$ go build sorter
[wangzheng@wangzheng-centos sorter]$ go install sorter
项目结构:
[wangzheng@wangzheng-centos sorter]$ tree
.
├── bin
│ └── sorter
├── pkg
│ └── linux_amd64
│ └── algorithm
│ ├── bubblesort.a
│ └── qsort.a
└── src
├── algorithm
│ ├── bubblesort
│ │ ├── bubblesort.go
│ │ └── bubblesort_test.go
│ └── qsort
│ ├── qsort.go
│ └── qsort_test.go
└── sorter
├── sorter
└── sorter.go
9 directories, 9 files
[wangzheng@wangzheng-centos sorter]$
[wangzheng@wangzheng-centos algorithm]$ pwd
/home/wangzheng/sorter/pkg/linux_amd64/algorithm
[wangzheng@wangzheng-centos algorithm]$ ls
bubblesort.a qsort.a
执行结果
未排序文件
[wangzheng@wangzheng-centos bin]$ cat unsorted.dat
123
3064
3
64
490
1
23
5331
2
7
4
2
132
[wangzheng@wangzheng-centos bin]$
排序
[wangzheng@wangzheng-centos bin]$ ./sorter -i unsorted.dat -o qsorted.dat -a qsort
infile = unsorted.dat outfile = qsorted.dat algorithm = qsort
The sorting process costs 1.625µs to complete.
[wangzheng@wangzheng-centos bin]$ ./sorter -i unsorted.dat -o bsorted.dat -a bubblesort
infile = unsorted.dat outfile = bsorted.dat algorithm = bubblesort
The sorting process costs 1.481µs to complete.
排序后
[wangzheng@wangzheng-centos bin]$ cat qsorted.dat
1
2
2
3
4
7
23
64
123
132
490
3064
5331
[wangzheng@wangzheng-centos bin]$ cat bsorted.dat
1
2
2
3
4
7
23
64
123
132
490
3064
5331
[wangzheng@wangzheng-centos bin]$