完成 ArrayN del 操作

This commit is contained in:
eson 2019-04-13 03:35:18 +08:00
parent 3b54163d06
commit 6389722a0c
6 changed files with 382 additions and 96 deletions

View File

@ -30,7 +30,7 @@ func (arr *Array2) Values() []interface{} {
}
}
} else {
for i := 0; i < arr.ysize; i++ {
for i := 0; i < arr.xsize; i++ {
result = append(result, nil)
}
}
@ -40,51 +40,51 @@ func (arr *Array2) Values() []interface{} {
}
func (arr *Array2) Set(idx int, value interface{}) {
yindex := idx / arr.ysize
xindex := idx % arr.ysize
yindex := idx / arr.xsize
xindex := idx % arr.xsize
ydata := arr.data[yindex]
if ydata == nil {
ydata = make([]interface{}, arr.xsize, arr.xsize)
arr.data[yindex] = ydata
xdata := arr.data[yindex]
if xdata == nil {
xdata = make([]interface{}, arr.xsize, arr.xsize)
arr.data[yindex] = xdata
}
if ydata[xindex] == nil {
if xdata[xindex] == nil {
arr.sizes[yindex]++
}
ydata[xindex] = value
xdata[xindex] = value
}
func (arr *Array2) Get(idx int) (interface{}, bool) {
yindex := idx / arr.ysize
xindex := idx % arr.ysize
yindex := idx / arr.xsize
xindex := idx % arr.xsize
ydata := arr.data[yindex]
if ydata == nil {
xdata := arr.data[yindex]
if xdata == nil {
return nil, false
}
xdata := ydata[xindex]
return xdata, xdata != nil
v := xdata[xindex]
return v, v != nil
}
func (arr *Array2) Del(idx int) (interface{}, bool) {
yindex := idx / arr.ysize
xindex := idx % arr.ysize
yindex := idx / arr.xsize
xindex := idx % arr.xsize
ydata := arr.data[yindex]
if ydata == nil {
xdata := arr.data[yindex]
if xdata == nil {
return nil, false
}
xdata := ydata[xindex]
ydata[xindex] = nil
v := xdata[xindex]
xdata[xindex] = nil
isnil := xdata != nil
isnil := v != nil
if isnil {
arr.sizes[yindex]--
if arr.sizes[yindex] == 0 {
arr.data[yindex] = nil
}
}
return xdata, isnil
return v, isnil
}

View File

@ -8,7 +8,7 @@ import (
"github.com/Pallinder/go-randomdata"
)
func TestArray2Set(t *testing.T) {
func testSet1(t *testing.T) {
arr := NewWithCap(4, 4)
l := []int{0, 6, 5, 15}
for _, v := range l {
@ -30,7 +30,34 @@ func TestArray2Set(t *testing.T) {
arr.Set(16, 16)
}
func TestArray2Get(t *testing.T) {
func testSet2(t *testing.T) {
arr := NewWithCap(3, 6)
l := []int{0, 6, 5, 15}
for _, v := range l {
arr.Set(v, v)
}
var result string
result = spew.Sprint(arr.Values())
if result != "[0 {} {} {} {} 5 6 {} <nil> <nil> <nil> <nil> {} {} {} 15]" {
t.Error(result)
}
defer func() {
if err := recover(); err == nil {
t.Error("err == nil, but array the set is out of range")
}
}()
arr.Set(16, 16)
}
func TestArray2Set(t *testing.T) {
testSet1(t)
testSet2(t)
}
func testArray2Get1(t *testing.T) {
arr := New()
for i := 0; i < 64; i++ {
arr.Set(i, i)
@ -55,8 +82,38 @@ func TestArray2Get(t *testing.T) {
arr.Get(64)
}
func testArray2Get2(t *testing.T) {
arr := NewWithCap(9, 8)
for i := 0; i < 64; i++ {
arr.Set(i, i)
}
for i := 0; i < 64; i++ {
if v, ok := arr.Get(i); ok {
if v != i {
t.Error("v is equal i, but", v, i)
}
} else {
t.Error("not ok is error")
}
}
defer func() {
if err := recover(); err == nil {
t.Error("err == nil, but array the get is out of range")
}
}()
arr.Get(72)
}
func TestArray2Get(t *testing.T) {
testArray2Get1(t)
testArray2Get2(t)
}
func TestArray2Del(t *testing.T) {
arr := NewWithCap(4, 4)
arr := NewWithCap(3, 6)
l := []int{0, 6, 5, 15}
for _, v := range l {
arr.Set(v, v)
@ -66,25 +123,27 @@ func TestArray2Del(t *testing.T) {
arr.Del(0)
result = spew.Sprint(arr.Values())
if result != "[<nil> <nil> <nil> <nil> {} 5 6 {} <nil> <nil> <nil> <nil> {} {} {} 15]" {
if result != "[{} {} {} {} {} 5 6 {} {} {} {} {} {} {} {} 15 {} {}]" {
t.Error(arr.data)
t.Error(result)
}
arr.Del(5)
result = spew.Sprint(arr.Values())
if result != "[<nil> <nil> <nil> <nil> {} {} 6 {} <nil> <nil> <nil> <nil> {} {} {} 15]" {
if result != "[<nil> <nil> <nil> <nil> <nil> <nil> 6 {} {} {} {} {} {} {} {} 15 {} {}]" {
t.Error(arr.data)
t.Error(result)
}
arr.Del(6)
result = spew.Sprint(arr.Values())
if result != "[<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> {} {} {} 15]" {
if result != "[<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> {} {} {} 15 {} {}]" {
t.Error(result)
}
arr.Del(15)
result = spew.Sprint(arr.Values())
if result != "[<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil>]" {
if result != "[<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil>]" {
t.Error(result)
}
@ -94,7 +153,7 @@ func TestArray2Del(t *testing.T) {
}
}()
arr.Del(16)
arr.Del(18)
}
func BenchmarkArray2Set(b *testing.B) {

View File

@ -1,11 +1,5 @@
package array3
import (
"log"
"github.com/davecgh/go-spew/spew"
)
type Array3 struct {
ysizes []int
xsizes [][]int
@ -37,7 +31,6 @@ func NewWithCap(zsize, ysize, xsize int) *Array3 {
func (arr *Array3) Values() []interface{} {
var result []interface{}
spew.Println(arr.data)
for _, z := range arr.data {
if z != nil {
@ -67,75 +60,71 @@ func (arr *Array3) Values() []interface{} {
}
func (arr *Array3) Set(idx int, value interface{}) {
zindex := idx / arr.xyproduct
nidx := (idx % arr.xyproduct)
yindex := nidx / arr.ysize
xindex := nidx % arr.ysize
log.Println(zindex, nidx, yindex, xindex)
zdata := arr.data[zindex]
if zdata == nil {
zdata = make([][]interface{}, arr.ysize, arr.ysize)
arr.data[yindex] = zdata
yindex := nidx / arr.xsize
xindex := nidx % arr.xsize
ydata := arr.data[zindex]
if ydata == nil {
ydata = make([][]interface{}, arr.ysize, arr.ysize)
arr.data[zindex] = ydata
}
ydata := zdata[yindex]
if ydata == nil {
ydata = make([]interface{}, arr.xsize, arr.xsize)
zdata[yindex] = ydata
xdata := ydata[yindex]
if xdata == nil {
xdata = make([]interface{}, arr.xsize, arr.xsize)
ydata[yindex] = xdata
arr.ysizes[zindex]++
}
xdata := ydata[xindex]
if xdata == nil {
v := xdata[xindex]
if v == nil {
arr.xsizes[zindex][yindex]++
}
ydata[xindex] = value
xdata[xindex] = value
}
func (arr *Array3) Get(idx int) (interface{}, bool) {
zindex := idx / arr.xyproduct
nextsize := (idx % arr.xyproduct)
yindex := nextsize / arr.ysize
xindex := nextsize % arr.ysize
yindex := nextsize / arr.xsize
xindex := nextsize % arr.xsize
zdata := arr.data[zindex]
if zdata == nil {
return nil, false
}
ydata := zdata[yindex]
ydata := arr.data[zindex]
if ydata == nil {
return nil, false
}
xdata := ydata[xindex]
return xdata, xdata != nil
xdata := ydata[yindex]
if xdata == nil {
return nil, false
}
v := xdata[xindex]
return v, v != nil
}
func (arr *Array3) Del(idx int) (interface{}, bool) {
zindex := idx / arr.xyproduct
nextsize := (idx % arr.xyproduct)
yindex := nextsize / arr.ysize
xindex := nextsize % arr.ysize
yindex := nextsize / arr.xsize
xindex := nextsize % arr.xsize
zdata := arr.data[zindex]
if zdata == nil {
return nil, false
}
ydata := zdata[yindex]
ydata := arr.data[zindex]
if ydata == nil {
return nil, false
}
xdata := ydata[xindex]
ydata[xindex] = nil
xdata := ydata[yindex]
if xdata == nil {
return nil, false
}
isnotnil := xdata != nil
v := xdata[xindex]
xdata[xindex] = nil
isnotnil := v != nil
if isnotnil {
arr.xsizes[zindex][yindex]--
@ -149,5 +138,5 @@ func (arr *Array3) Del(idx int) (interface{}, bool) {
}
}
return xdata, isnotnil
return v, isnotnil
}

View File

@ -8,17 +8,16 @@ import (
"github.com/Pallinder/go-randomdata"
)
func TestSet(t *testing.T) {
arr := NewWithCap(3, 3, 3)
l := []int{0, 6, 5, 9, 15}
func testSet1(t *testing.T) {
arr := NewWithCap(2, 2, 2)
l := []int{0, 1, 7}
for _, v := range l {
arr.Set(v, v)
spew.Sprint(arr.Values())
}
var result string
result = spew.Sprint(arr.Values())
if result != "[0 {} {} {} {} 5 6 {} <nil> <nil> <nil> <nil> {} {} {} 15]" {
if result != "[0 1 <nil> <nil> <nil> <nil> {} 7]" {
t.Error(result)
}
@ -28,10 +27,38 @@ func TestSet(t *testing.T) {
}
}()
arr.Set(16, 16)
arr.Set(8, 8)
}
func TestGet(t *testing.T) {
func testSet2(t *testing.T) {
arr := NewWithCap(2, 2, 3)
l := []int{0, 6, 5, 11}
for _, v := range l {
arr.Set(v, v)
}
var result string
result = spew.Sprint(arr.Values())
if result != "[0 {} {} {} {} 5 6 {} {} {} {} 11]" {
t.Error(arr.data)
t.Error(result)
}
defer func() {
if err := recover(); err == nil {
t.Error("err == nil, but array the set is out of range")
}
}()
arr.Set(12, 12)
}
func TestArray2Set(t *testing.T) {
testSet1(t)
testSet2(t)
}
func testArray2Get1(t *testing.T) {
arr := New()
for i := 0; i < 64; i++ {
arr.Set(i, i)
@ -56,9 +83,39 @@ func TestGet(t *testing.T) {
arr.Get(64)
}
func TestDel(t *testing.T) {
arr := NewWithCap(4, 4, 4)
l := []int{0, 6, 5, 15}
func testArray2Get2(t *testing.T) {
arr := NewWithCap(4, 3, 3)
for i := 0; i < 64; i++ {
arr.Set(i, i)
}
for i := 0; i < 64; i++ {
if v, ok := arr.Get(i); ok {
if v != i {
t.Error("v is equal i, but", v, i)
}
} else {
t.Error("not ok is error")
}
}
defer func() {
if err := recover(); err == nil {
t.Error("err == nil, but array the get is out of range")
}
}()
arr.Get(72)
}
func TestArray2Get(t *testing.T) {
testArray2Get1(t)
testArray2Get2(t)
}
func TestArray2Del(t *testing.T) {
arr := NewWithCap(2, 2, 3)
l := []int{0, 6, 5, 11}
for _, v := range l {
arr.Set(v, v)
}
@ -67,25 +124,27 @@ func TestDel(t *testing.T) {
arr.Del(0)
result = spew.Sprint(arr.Values())
if result != "[<nil> <nil> <nil> <nil> {} 5 6 {} <nil> <nil> <nil> <nil> {} {} {} 15]" {
if result != "[<nil> <nil> <nil> {} {} 5 6 {} {} {} {} 11]" {
t.Error(arr.data)
t.Error(result)
}
arr.Del(5)
result = spew.Sprint(arr.Values())
if result != "[<nil> <nil> <nil> <nil> {} {} 6 {} <nil> <nil> <nil> <nil> {} {} {} 15]" {
if result != "[<nil> <nil> <nil> <nil> <nil> <nil> 6 {} {} {} {} 11]" {
t.Error(arr.data)
t.Error(result)
}
arr.Del(6)
result = spew.Sprint(arr.Values())
if result != "[<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> {} {} {} 15]" {
if result != "[<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> {} {} 11]" {
t.Error(result)
}
arr.Del(15)
arr.Del(11)
result = spew.Sprint(arr.Values())
if result != "[<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil>]" {
if result != "[<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil>]" {
t.Error(result)
}
@ -95,10 +154,10 @@ func TestDel(t *testing.T) {
}
}()
arr.Del(16)
arr.Del(18)
}
func BenchmarkSet(b *testing.B) {
func BenchmarkArray2Set(b *testing.B) {
arr := NewWithCap(100, 100, 10)
b.N = 500000000
@ -117,7 +176,7 @@ func BenchmarkSet(b *testing.B) {
}
func BenchmarkGet(b *testing.B) {
func BenchmarkArray2Get(b *testing.B) {
arr := NewWithCap(100, 100, 10)
b.N = 500000000
@ -136,7 +195,7 @@ func BenchmarkGet(b *testing.B) {
}
func BenchmarkDel(b *testing.B) {
func BenchmarkArray2Del(b *testing.B) {
arr := NewWithCap(100, 100, 10)
b.N = 500000000

View File

@ -0,0 +1,126 @@
package arrayn
type SizeN struct {
Sizes []int
}
type ProductN struct {
Values []int
}
type DimensionSize struct {
Sizes []int
}
type Node struct {
size int
data interface{}
}
type ArrayN struct {
dims []int
product []int
dim int
data *Node // []*Node
}
func New() *ArrayN {
return NewWithCap(8, 8, 8)
}
func NewWithCap(dims ...int) *ArrayN {
arr := &ArrayN{dim: len(dims), dims: dims}
arr.product = make([]int, len(dims)-1, len(dims)-1)
for i := 0; i < len(dims)-1; i++ {
pvalue := 1
for n := i + 1; n < len(dims); n++ {
pvalue *= dims[n]
}
arr.product[i] = pvalue
}
// arr.data = make([]*Node, arr.dims[0], arr.dims[0])
return arr
}
func (arr *ArrayN) Values() []interface{} {
return nil
}
func (arr *ArrayN) set(curDim int, curidx int, data **Node, parent *Node) (*Node, int) {
sidx := arr.dim - curDim
if *data == nil {
if parent != nil {
parent.size++
}
if curDim > 1 {
*data = &Node{data: make([]*Node, arr.dims[sidx], arr.dims[sidx])}
} else {
*data = &Node{data: make([]interface{}, arr.dims[sidx], arr.dims[sidx])}
return *data, curidx
}
}
if curDim == 1 {
return *data, curidx
}
nidx := curidx % arr.product[sidx]
dimindex := curidx / arr.product[sidx]
cur := *data
return arr.set(curDim-1, nidx, &cur.data.([]*Node)[dimindex], cur)
}
func (arr *ArrayN) get(curDim int, curidx int, data **Node) (*Node, int) {
sidx := arr.dim - curDim
if *data == nil {
return nil, 0
}
if curDim == 1 {
return *data, curidx
}
nidx := curidx % arr.product[sidx]
dimindex := curidx / arr.product[sidx]
cur := *data
return arr.get(curDim-1, nidx, &cur.data.([]*Node)[dimindex])
}
func (arr *ArrayN) Set(idx int, value interface{}) {
n, nidx := arr.set(arr.dim, idx, &arr.data, nil)
n.data.([]interface{})[nidx] = value
}
func (arr *ArrayN) Get(idx int) (interface{}, bool) {
n, nidx := arr.get(arr.dim, idx, &arr.data)
if n != nil {
v := n.data.([]interface{})[nidx]
return v, v != nil
}
return nil, false
}
func (arr *ArrayN) del(curDim int, curidx int, data **Node) (*Node, int) {
sidx := arr.dim - curDim
if *data == nil {
return nil, 0
}
if curDim == 1 {
return *data, curidx
}
nidx := curidx % arr.product[sidx]
dimindex := curidx / arr.product[sidx]
cur := *data
return arr.del(curDim-1, nidx, &cur.data.([]*Node)[dimindex])
}
func (arr *ArrayN) Del(idx int) (interface{}, bool) {
return nil, true
}

View File

@ -0,0 +1,53 @@
package arrayn
import (
"testing"
"github.com/Pallinder/go-randomdata"
)
func TestCase1(t *testing.T) {
arr := NewWithCap(3, 3, 3, 3)
for i := 0; i < 52; i++ {
arr.Set(i, i)
}
t.Error(arr.Get(2))
t.Error(arr.Get(1))
t.Error(arr.Get(80))
}
func BenchmarkGoMap(b *testing.B) {
m := make(map[int]bool)
b.N = 50000000
b.StopTimer()
var l []int
for i := 0; i < b.N/10; i++ {
l = append(l, randomdata.Number(0, 100000000))
}
b.StartTimer()
for c := 0; c < 10; c++ {
for i := 0; i < b.N/10; i++ {
m[l[i]] = true
}
}
}
func BenchmarkArrayNSet(b *testing.B) {
arr := NewWithCap(10, 10, 10, 10000)
b.N = 10000000
b.StopTimer()
var l []int
for i := 0; i < b.N/10; i++ {
l = append(l, randomdata.Number(0, 10000000))
}
b.StartTimer()
for c := 0; c < 10; c++ {
for i := 0; i < b.N/10; i++ {
arr.Set(l[i], i)
}
}
}