红桥网站建设公司做个网站多少钱大概
红桥网站建设公司,做个网站多少钱大概,网站营销活动页面制作,ui设计的定义数据结构-哈希算法
哈希原理
hash哈希是一种算法
y hash(x) 给定一个x一定得到固定的yx是输入#xff0c;x取值范围称为输入空间#xff0c;x是任意值#xff0c;x是任意长度#xff08;go中字节序列#xff09;y是输出#xff0c;y取值范围称为输出空间#xff0c;…数据结构-哈希算法
哈希原理
hash哈希是一种算法
y hash(x) 给定一个x一定得到固定的yx是输入x取值范围称为输入空间x是任意值x是任意长度go中字节序列y是输出y取值范围称为输出空间但输出内容是固定长度的字节序列长度固定输入是无穷个但是固定字节的输出却能表示的状态是有限个一定存在xm、xn经过hash函数算出的y值一样把不同x值求得y值一样的情况称为hash冲突他们碰撞了hash算法设计还要兼顾 高效 x一个微小的变化哪怕是一个bit位的变化也将引起结果y巨大的变化hash不可逆不能从结果反推输入值单向散列算法 不可逆用在KEY的计算上
哈希算法 MD5Message Digest Algorithm 5信息摘要算法5输出是128位。运算速度叫SHA-1快 用户密码存储上传、下载文件完整性校验大的数据的快速比对例如字段很大增加一个字段存储该字段的hash值对比内容开是否修改 SHASecure Hash Algorithm安全散列算法包含一个系列算法分别是SHA-1、SHA-224、SHA-256、SHA-384和SHA-512。 数字签名防篡改 package mainimport (crypto/sha256fmt
)func main() {h : sha256.New()h.Write([]byte(abc))// 提供字节流r : h.Sum(nil)s : fmt.Sprintf(%x, r) // 把字节序列的每个字节以16进制显示fmt.Printf(%T %s %d \n, r, s, len(s))
}
[]uint8 e4b0cf398b77ac6efb797544d268782dc7d082e59c4d1aff15f3ae661588f0eb 64 映射 映射Map也有语言称为字典 长度可变 存储的元素是key-value对键值对value可变 key无序不重复 不可索引需要通过key来访问 不支持零值可用也就是说必须要用make或字面常量构造 引用类型 哈希表
内存模型
map采用哈希表实现。Go的map类型也是引用类型有一个标头值hmap指向一个底层的哈希表。
哈希表 存储kv对一个kv对称为一个元素键值对entry、item len表示元素的个数即 kv对的个数cap不能用 key 不能重复无序 key按照某种先后顺序加入到map中但是从哈希表中看不出顺序来key是关键的还有唯一的意思相同key会 去重 引用类型 有一个标头值有一个指针指向底层的hash表 不支持零值可用
哈希表原理 yhash(x)
开辟一块内存空间分割出一个个“房间”这个房间称为bucket桶按照y值为“房间”编号 使用给出的x计算出对应的y值可以按照某种关系计算出数据将被存储到的“房间号码”将数据存 入该房间 即使是hash函数设计的好数据分布均匀但是存储的数据很多超过负载因子则需要扩容 否则再加入数据后冲突太多引起效率低下
hash冲突
房间有人占了就重新找个空房间让客人住这是开放地址法房间有人占了就挤在同一个房间内将值用链表存储在一起这是链地址法也称拉链法Go语言采用但做了一定的优化
理解有key hash后的key value 三种
1、如果key相同 则hash后的key一定相同
2、key不相同但是存在hash后的key是相同的也就是房间号是相同
我们可以理解hash后的key为房间号hash冲突就是hash后的key是相同的若hash就的key是相同的可以存放在一个房间里面在这个房间里面可以放几个key-value对若是查找这个key-value先找到这个房间在这个房间内在查找key
构造 func main() {var m1 map[string]int // nil很危险。map不是零值可用fmt.Println(m1, m1 nil)m1[t] 200 // panic不可以
}
//结论零值不可用用var a map[int]int 零值是nil但是后面无法增加kv对// 1 字面量
//字面量定义map[string]int{k1:v1} 花括号表示字面量
func main() {var m0 map[string]int{} // 安全没有一个键值对而已fmt.Println(m0)
}
map[]func main() {var m1 map[string]int{a: 11,b: 22,c: 33,}fmt.Println(m1)}
map[a:11 b:22 c:33]
//make
func main() {m2 : make(map[int]string) // 一个较小的起始空间大小//make(map[string]int) // 没有告诉未来容纳多少元素先开辟较小空间如果未来kv对较多可能频繁扩容m2[100] abcm3 : make(map[int]string, 100) // 分配足够容量来容纳100个元素长度为0。为了减少扩容可以提前给出元素个数fmt.Println(m2, m3)
}map[100:abc] map[]//结论
make(map[string]int, 100) 表示为100个元素自动生成足够内部按照算法生成的空间 make(map[string]int, 100) 告诉未来容纳多少元素先开辟合适的空间来存储这些kv对注意一般空间大小别元素个数大一些
var m0 map[string]int 这不是赋值语句go语言零值可用但是这是引用类型所以是nil新增或修改
func main() {var m make(map[string]int)m[a] 11 // key不存在则创建新的key和value对m[a] 22 // key已经存在则覆盖valuefmt.Println(m)
}
map[a:22]查找
使用map一般需要使用key来查找时间复杂度为O(1)
func main() {var m make(map[string]int)m[a] 11m[a] 22if _, ok : m[b]; ok {fmt.Println(存在)} else {fmt.Println(不存在)}
}key访问map最高效的方式
长度
// 返回kv对的个数
func main() {var m make(map[string]int)m[a] 11m[a] 22fmt.Println(len(m))
}
1注意由于map的特殊构造不能使用cap。
移除
func main() {var m make(map[string]int)m[a] 11 m[b] 22fmt.Println(m)delete(m, a)// 存在删除kv对fmt.Println(m)}map[a:11 b:22]
map[b:22]
即便不存在删除也不会panic遍历
func main() {var m map[string]int{a: 11,b: 22,c: 33,}for k, v : range m {fmt.Println(k, v)}
}
a 11
b 22
c 33注意map的key是无序的千万不要从遍历结果来推测其内部顺序因为key在内存中是乱序
排序sort
Go的标准库提供了sort库用来给线性数据结构排序、二分查找。
升序
// 切片排序
// 针对int、string有快捷方法Ints、Strings
func main() {var a []int{-1, 23, 5, 7, 4, 9}sort.Ints(a)// 就地修改原切片的底层数组// sort.Sort(sort.IntSlice(a)) // sort.IntSlice(a)强制类型转换以施加接口方法fmt.Println(a)// 默认升序
}
[-1 4 5 7 9 23]func main() {b : []string{xyz, a, abc, Ab, X}sort.Strings(b)fmt.Println(b)
}
[Ab X a abc xyz] //根据ascill码排序降序
降序和升序不同 升序在go中已经定义好了 只需要调用 但是降序不行 func main() {b : []string{xyz, a, abc, Ab, X}sort.Sort(sort.Reverse(sort.StringSlice(b))) //Reverse取反fmt.Println(b)
}
[xyz abc a X Ab]二分查找
前提必须先排序并且是升序
func main() {// 二分查找a : []int{-1, 23, 5, 9, 7}sort.Ints(a)// 二分查找必须是升序// 二分查找的前提是 有序i : sort.SearchInts(a, 1) fmt.Println(i)
}
1
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/87268.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!