Golang可变长数组

news/2024/7/9 21:20:07 标签: golang, linux, postgresql

可变长数组

代码实现

package zgo_algorithm

import (
	"fmt"
	"sync"
)

// Array 可变长数组
type Array struct {
	array []int      // 固定大小的数组,用满容量和满大小的切片来代替
	len   int        // 真正长度
	cap   int        // 容量
	lock  sync.Mutex // 为了并发安全使用的锁
}

// MakeArray 新建一个可变长数组
// 时间复杂度为:O(1),因为分配内存空间和设置几个值是常数时间。
func MakeArray(len, cap int) *Array {
	s := new(Array)
	if len > cap {
		panic("数组的长度不能大于容量")
	}

	// 把切片当数组用
	array := make([]int, cap, cap)

	// 元数据
	s.array = array
	s.cap = cap
	s.len = 0
	return s
}

// Append 增加一个元素
// 添加元素中,耗时主要在老数组中的数据移动到新数组,时间复杂度为:O(n)
func (a *Array) Append(element int) {
	// 并发锁
	a.lock.Lock()
	defer a.lock.Unlock()

	// 大小等于容量,表示没多余位置了
	if a.len == a.cap {
		// 没容量,数组要扩容,扩容到两倍
		newCap := 2 * a.len

		// 如果之前的容量为0,那么新容量为1
		if a.cap == 0 {
			newCap = 1
		}

		newArray := make([]int, newCap, newCap)

		// 把老数组的数据移动到新数组
		for k, v := range a.array {
			newArray[k] = v
		}

		// 替换数组
		a.array = newArray
		a.cap = newCap

	}

	// 把元素放在数组里
	a.array[a.len] = element
	// 真实长度+1
	a.len = a.len + 1

}

// AppendMany 增加多个元素
func (a *Array) AppendMany(element ...int) {
	for _, v := range element {
		a.Append(v)
	}
}

// Get 获取某个下标的元素
// 因为只获取下标的值,所以时间复杂度为 O(1)
func (a *Array) Get(index int) int {
	// 越界了
	if a.len == 0 || index >= a.len {
		panic("索引超过了长度")
	}
	return a.array[index]
}

// Len 返回真实长度
// 时间复杂度为 O(1)
func (a *Array) Len() int {
	return a.len
}

// Cap 返回容量
// 时间复杂度为 O(1)
func (a *Array) Cap() int {
	return a.cap
}

// 转换为字符串输出,主要用于打印
func (a *Array) ToString() (result string) {
	result = "["
	for i := 0; i < a.Len(); i++ {
		// 第一个元素
		if i == 0 {
			result = fmt.Sprintf("%s%d", result, a.Get(i))
			continue
		}

		result = fmt.Sprintf("%s %d", result, a.Get(i))
	}
	result = result + "]"
	return
}

测试

package zgo_algorithm

import (
	"fmt"
	"testing"
)

func TestArray(t *testing.T) {
	// 创建一个容量为3的动态数组
	a := MakeArray(0, 3)
	fmt.Println("cap", a.Cap(), "len", a.Len(), "array:", a.ToString())

	// 增加一个元素
	a.Append(10)
	fmt.Println("cap", a.Cap(), "len", a.Len(), "array:", a.ToString())

	// 增加一个元素
	a.Append(9)
	fmt.Println("cap", a.Cap(), "len", a.Len(), "array:", a.ToString())

	// 增加多个元素
	a.AppendMany(8, 7)
	fmt.Println("cap", a.Cap(), "len", a.Len(), "array:",a.ToString())

}

输出结果

=== RUN   TestArray
cap 3 len 0 array: []
cap 3 len 1 array: [10]
cap 3 len 2 array: [10 9]
cap 6 len 4 array: [10 9 8 7]
--- PASS: TestArray (0.00s)
PASS

http://www.niftyadmin.cn/n/795885.html

相关文章

随堂小测app冲刺(一)

项目来源&#xff1a;这个项目是从婷婷姐那里拿来的&#xff0c;这个项目的思路一开始是个小程序&#xff0c;所以团队一开始在想&#xff0c;到底是做个安卓&#xff0c;还是继续做小程序&#xff1f;我们最终还是选做安卓 原因无非两个;一&#xff0c;安卓是我们早晚要学习的…

Golang数组栈

代码实现 package zgo_algorithmimport "sync"// 数组栈&#xff0c;后进先出 type ArrayStack struct {array []string // 底层切片size int // 栈的元素数量lock sync.Mutex // 为了并发安全使用的锁 }// 入栈 func (stack *ArrayStack) Push(v string…

Golang链表栈

代码实现 链表 // 最简单的链表 type LinkNode struct {Value interface{}Next *LinkNode }链表栈 // 链表栈&#xff0c;后进先出 type LinkStack struct {root *LinkNode // 链表起点size int // 栈的元素数量lock sync.Mutex // 为了并发安全使用的锁 }// 入栈 /…

oppoJava面试!java写文件换行符

什么是数据库 数据库就是存储数据的地方&#xff0c;好比家里的冰箱用来存放食物&#xff0c;衣柜用来存放衣物… 正是有了数据库之后&#xff0c;我们可以直接查找数据。比如你每天看余额宝账户的收益&#xff0c;其实就是数据库从后台读取给你的。 常见的数据库面试题有&am…

Golang数组队列

代码实现 package zgo_algorithmimport "sync"// 数组队列&#xff0c;先进先出 // 队列先进先出&#xff0c;和栈操作顺序相反&#xff0c;我们这里只实现入队&#xff0c;和出队操作&#xff0c;其他操作和栈一样。 type ArrayQueue struct {array []interface{} …

Git---基础

1. 最小配置&#xff0c;即配置用户信息 Email &#xff1a;git会自动提取用来发送邮件&#xff08;注意一定是可以收取邮件的&#xff09;&#xff0c;name &#xff1a;标识身份 注意&#xff1a;空格不要等号 用来处理本机多个仓库 local命令必须在git项目中才可以使用&…

Golang链表队列

代码实现 链表 // 最简单的链表 type LinkNode struct {Value interface{}Next *LinkNode }队列 // 链表队列&#xff0c;先进先出 type LinkQueue struct {root *LinkNode // 链表起点size int // 队列的元素数量lock sync.Mutex // 为了并发安全使用的锁 }// 入队…

软件工程(2019)结对编程第二次作业

1 题目要求 我们在刚开始上课的时候介绍过一个小学四则运算自动生成程序的例子&#xff0c;请实现它&#xff0c;要求&#xff1a; 能够自动生成四则运算练习题可以定制题目数量用户可以选择运算符用户设置最大数&#xff08;如十以内、百以内等&#xff09;用户选择是否有括号…