最近閱讀<<個人第一本算法書>>(【日】石田保輝;宮崎修一)
本系列筆記擬採用golang練習之golang
數組是一種線性數據結構, 數據按順序存儲在內存的連續空間內。 每一個數據的內存地址(在內存上的位置)均可以經過數組下標算出, 咱們也就能夠藉此直接訪問目標數據(這叫做「隨機訪問」)。 訪問數據時使用的是隨機訪問(經過下標可計算出內存地址), 因此須要的運行時間僅爲恆定的O(1)。 但另外一方面,想要向數組中添加新數據時,必須把目標位置後面的數據一個個移開。 因此,若是在數組頭部添加數據,就須要O(n)的時間。 刪除操做同理。 摘自 <<個人第一本算法書>>(【日】石田保輝;宮崎修一)
array_test.go算法
package data_structure import ( "learning/gooop/data_structure/array" "testing" ) func Test_Array(t *testing.T) { fnAssertTrue := func(b bool, msg string) { if !b { t.Fatal(msg) } } it := array.NewArray() t.Log(it.String()) fnAssertTrue(it.String() == "[]", "expecting []") it.Append(1) t.Log(it.String()) fnAssertTrue(it.String() == "[1]", "expecting [1]") e := it.Remove(0) t.Log(it.String()) fnAssertTrue(e == nil, "expecting e == nil") fnAssertTrue(it.String() == "[]", "expecting []") e = it.Insert(0, 1) t.Log(it.String()) fnAssertTrue(e == nil, "expecting e == nil") fnAssertTrue(it.String() == "[1]", "expecting [1]") e = it.Insert(0, 0) t.Log(it.String()) fnAssertTrue(e == nil, "expecting e == nil") fnAssertTrue(it.String() == "[0,1]", "expecting [0,1]") e = it.Insert(2, 2) t.Log(it.String()) fnAssertTrue(e == nil, "expecting e == nil") fnAssertTrue(it.String() == "[0,1,2]", "expecting [0,1,2]") e = it.Set(0, 10) t.Log(it.String()) fnAssertTrue(e == nil, "expecting e == nil") fnAssertTrue(it.String() == "[10,1,2]", "expecting [10,1,2]") e = it.Set(2, 20) t.Log(it.String()) fnAssertTrue(e == nil, "expecting e == nil") fnAssertTrue(it.String() == "[10,1,20]", "expecting [10,1,20]") e,x := it.Get(0) fnAssertTrue(e == nil, "expecting e == nil") fnAssertTrue(x == 10, "expecting 10") e,x = it.Get(2) fnAssertTrue(e == nil, "expecting e == nil") fnAssertTrue(x == 20, "expecting 20") e,_ = it.Get(3) fnAssertTrue(e != nil, "expecting e != nil") e,_ = it.Get(-1) fnAssertTrue(e != nil, "expecting e != nil") }
$ go test -v array_test.go === RUN Test_Array array_test.go:16: [] array_test.go:20: [1] array_test.go:24: [] array_test.go:29: [1] array_test.go:34: [0,1] array_test.go:39: [0,1,2] array_test.go:44: [10,1,2] array_test.go:49: [10,1,20] --- PASS: Test_Array (0.00s) PASS ok command-line-arguments 0.002s
定義數組的接口數組
package array type IArray interface { Size() int IsEmpty() bool IsNotEmpty() bool Get(i int) (error,interface{}) Set(i int, it interface{}) error Append(it interface{}) Remove(i int) error Insert(i int, it interface{}) error Iterator() IArrayIterator String() string }
定義數組的迭代器數據結構
package array type IArrayIterator interface { More() bool Next() (error,interface{}) }
數組的OO封裝, 實現IArray接口app
package array import ( "errors" "fmt" "strings" ) type tCustomArray struct { items []interface{} size int } var gIndexOutofBoundsError = errors.New("index out of bounds") func NewArray() IArray { return &tCustomArray{ items: make([]interface{}, 0), size: 0, } } func (me *tCustomArray) Size() int { return me.size } func (me *tCustomArray) IsEmpty() bool { return me.size <= 0 } func (me *tCustomArray) IsNotEmpty() bool { return !me.IsEmpty() } func (me *tCustomArray) Get(i int) (error,interface{}) { if i >= me.size || i < 0 { return gIndexOutofBoundsError, nil } return nil, me.items[i] } func (me *tCustomArray) Set(i int, it interface{}) error { if i >= me.size || i < 0 { return gIndexOutofBoundsError } me.items[i] = it return nil } func (me *tCustomArray) Append(it interface{}) { me.items = append(me.items, it) me.size++ } func (me *tCustomArray) Remove(i int) error { if i >= me.size || i < 0 { return gIndexOutofBoundsError } me.items = append(me.items[:i], me.items[i+1:]...) me.size-- return nil } func (me *tCustomArray) Insert(i int, it interface{}) error { if i > me.size || i < 0 { return gIndexOutofBoundsError } newItems := make([]interface{}, 0) newItems = append(newItems, me.items[:i]...) newItems = append(newItems, it) newItems = append(newItems, me.items[i:]...) me.items = newItems me.size++ return nil } func (me *tCustomArray) Iterator() IArrayIterator { return newArrayIterator(me.items) } func (me *tCustomArray) String() string { ss := make([]string, me.size) for i,it := range me.items { ss[i] = fmt.Sprintf("%v", it) } return fmt.Sprintf("[%s]", strings.Join(ss, ",")) }
數組迭代器, 實現IArrayIterator接口oop
package array type tArrayIterator struct { items []interface{} count int pos int } func newArrayIterator(items []interface{}) IArrayIterator { size := len(items) copy := make([]interface{}, size) for i,it := range items { copy[i] = it } return &tArrayIterator{ items: copy, count: size, pos: 0, } } func (me *tArrayIterator) More() bool { return me.pos < me.count } func (me *tArrayIterator) Next() (error,interface{}) { if me.pos >= me.count { return gIndexOutofBoundsError, nil } n := me.pos me.pos++ return nil, me.items[n] }
(end)單元測試