初始化项目

This commit is contained in:
皮蛋13361098506
2025-01-06 16:01:02 +08:00
commit 1b77f62820
575 changed files with 69193 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
/*
数学助手包,提供一些与数学相关的助手方法
*/
package mathUtil

View File

@@ -0,0 +1,5 @@
package mathUtil
type IWeight interface {
GetWeight() int
}

View File

@@ -0,0 +1,33 @@
package mathUtil
import (
"fmt"
)
// int类型区间对象表示连续的int类型区间
type IntRegion struct {
Lower int
Upper int
}
func (this *IntRegion) String() string {
return fmt.Sprintf("%d-%d", this.Lower, this.Upper)
}
// 是否包含指定的值
func (this *IntRegion) Contains(value int) bool {
return this.Lower <= value && value <= this.Upper
}
// 是否是有序的
func (this *IntRegion) IsSorted() bool {
return this.Lower < this.Upper
}
// 创建int类型区间对象
func NewIntRegion(lower, upper int) *IntRegion {
return &IntRegion{
Lower: lower,
Upper: upper,
}
}

View File

@@ -0,0 +1,186 @@
package mathUtil
import (
"sort"
)
// 判断传入的byte型数组是否连续
func IsContinuous_byte(list []byte) bool {
if len(list) == 0 || len(list) == 1 {
return true
}
list_int64 := make([]int64, len(list), len(list))
for i, v := range list {
list_int64[i] = int64(v)
}
return IsContinuous_int64(list_int64)
}
// 判断传入的int型数组是否连续
func IsContinuous_int(list []int) bool {
if len(list) == 0 || len(list) == 1 {
return true
}
list_int64 := make([]int64, len(list), len(list))
for i, v := range list {
list_int64[i] = int64(v)
}
return IsContinuous_int64(list_int64)
}
// 判断传入的int型数组是否连续
func IsContinuous_int32(list []int32) bool {
if len(list) == 0 || len(list) == 1 {
return true
}
list_int64 := make([]int64, len(list), len(list))
for i, v := range list {
list_int64[i] = int64(v)
}
return IsContinuous_int64(list_int64)
}
// 判断传入的int型数组是否连续
func IsContinuous_int64(list []int64) bool {
if len(list) == 0 || len(list) == 1 {
return true
}
if int64(len(list)) != list[len(list)-1]-list[0]+1 {
return false
}
for i := 0; i < len(list)-1; i++ {
if list[i]+1 != list[i+1] {
return false
}
}
return true
}
// 判断区间是否连续
func IsContinuous_Region(list []*IntRegion) bool {
if len(list) == 0 || len(list) == 1 {
return true
}
sort.Slice(list, func(i, j int) bool { return list[i].Lower < list[j].Lower })
for i := 0; i < len(list)-1; i++ {
if list[i].IsSorted() == false || list[i+1].IsSorted() == false {
return false
}
if list[i].Upper+1 != list[i+1].Lower {
return false
}
}
return true
}
// 判断传入的概率是否全覆盖
func IsOddFullConvered(list []*IntRegion, min, max int) bool {
if len(list) == 0 {
return false
}
if list[0].Lower != min || list[len(list)-1].Upper != max {
return false
}
sort.Slice(list, func(i, j int) bool { return list[i].Lower < list[j].Lower })
for i := 0; i < len(list)-1; i++ {
if list[i].IsSorted() == false || list[i+1].IsSorted() == false {
return false
}
if list[i].Upper+1 != list[i+1].Lower {
return false
}
}
return true
}
func IsDistinct_byte(list []byte) (result bool) {
if len(list) == 0 || len(list) == 1 {
result = true
return
}
list_int64 := make([]int64, len(list), len(list))
for i, v := range list {
list_int64[i] = int64(v)
}
return IsDistinct_int64(list_int64)
}
func IsDistinct_int(list []int) (result bool) {
if len(list) == 0 || len(list) == 1 {
result = true
return
}
list_int64 := make([]int64, len(list), len(list))
for i, v := range list {
list_int64[i] = int64(v)
}
return IsDistinct_int64(list_int64)
}
func IsDistinct_int32(list []int32) (result bool) {
if len(list) == 0 || len(list) == 1 {
result = true
return
}
list_int64 := make([]int64, len(list), len(list))
for i, v := range list {
list_int64[i] = int64(v)
}
return IsDistinct_int64(list_int64)
}
// 判断int64数组是否内容唯一
func IsDistinct_int64(list []int64) (result bool) {
if len(list) == 0 || len(list) == 1 {
result = true
return
}
sort.Slice(list, func(i, j int) bool { return list[i] < list[j] })
for i := 0; i < len(list)-1; i++ {
if list[i] == list[i+1] {
result = false
return
}
}
result = true
return
}
//// 将int转成uint类型(因goutil指定go版本过低不支持泛型未实际加入要使用的人取消注释并指定允许泛型的go版本)
//// 应用场景atomic.AddUint64 想减1时
////
//// x := uint64(1000)
//// y := int64(-1)
//// atomic.AddUint64(&x, intToUint[int64, uint64](y))
//func intToUint[T1 int8 | int16 | int32 | int64 | int, T2 uint8 | uint16 | uint32 | uint64 | uint](x T1) T2 {
// // 写到函数内,两种方式都可以;若直接使用,只能使用^T2(-x - 1)若使用T2(x)方式x为负值时转为uint类语法检查无法通过
// return ^T2(-x - 1)
// // return T2(x)
//}

View File

@@ -0,0 +1,267 @@
package mathUtil
import (
"fmt"
"testing"
)
func TestIsContinuous_byte(t *testing.T) {
list := make([]byte, 0, 8)
if IsContinuous_byte(list) == false {
t.Errorf("it's should be true, but now false-------1")
}
list = append(list, 1)
if IsContinuous_byte(list) == false {
t.Errorf("it's should be true, but now false-------2")
}
list = append(list, 2)
list = append(list, 3)
list = append(list, 4)
list = append(list, 5)
if IsContinuous_byte(list) == false {
t.Errorf("it's should be true, but now false-------3")
}
list = append(list, 10)
if IsContinuous_byte(list) == true {
t.Errorf("it's should be false, but now true-------3")
}
}
func TestIsContinuous_int(t *testing.T) {
list := make([]int, 0, 8)
if IsContinuous_int(list) == false {
t.Errorf("it's should be true, but now false-------1")
}
list = append(list, 11)
if IsContinuous_int(list) == false {
t.Errorf("it's should be true, but now false-------2")
}
list = append(list, 12)
list = append(list, 13)
list = append(list, 14)
list = append(list, 15)
if IsContinuous_int(list) == false {
t.Errorf("it's should be true, but now false-------3")
}
list = append(list, 10)
if IsContinuous_int(list) == true {
t.Errorf("it's should be false, but now true-------3")
}
}
func TestIsContinuous_int32(t *testing.T) {
list := make([]int32, 0, 8)
if IsContinuous_int32(list) == false {
t.Errorf("it's should be true, but now false-------1")
}
list = append(list, 1)
if IsContinuous_int32(list) == false {
t.Errorf("it's should be true, but now false-------2")
}
list = append(list, 2)
list = append(list, 3)
list = append(list, 4)
list = append(list, 5)
if IsContinuous_int32(list) == false {
t.Errorf("it's should be true, but now false-------3")
}
list = append(list, 10)
if IsContinuous_int32(list) == true {
t.Errorf("it's should be false, but now true-------3")
}
}
func TestIsContinuous_int64(t *testing.T) {
list := make([]int64, 0, 8)
if IsContinuous_int64(list) == false {
t.Errorf("it's should be true, but now false-------1")
}
list = append(list, 1)
if IsContinuous_int64(list) == false {
t.Errorf("it's should be true, but now false-------2")
}
list = append(list, 2)
list = append(list, 3)
list = append(list, 4)
list = append(list, 5)
if IsContinuous_int64(list) == false {
t.Errorf("it's should be true, but now false-------3")
}
list = append(list, 10)
if IsContinuous_int64(list) == true {
t.Errorf("it's should be false, but now true-------3")
}
}
func TestIsContinuous_Region(t *testing.T) {
list := make([]*IntRegion, 0, 8)
if IsContinuous_Region(list) == false {
t.Errorf("it's should be true, but now false-------1")
}
list = append(list, NewIntRegion(101, 110))
if IsContinuous_Region(list) == false {
t.Errorf("it's should be true, but now false-------1")
}
list = append(list, NewIntRegion(1, 10))
if IsContinuous_Region(list) == true {
t.Errorf("it's should be false, but now true-------2")
}
list = append(list, NewIntRegion(11, 100))
if IsContinuous_Region(list) == false {
t.Errorf("it's should be true, but now false-------3")
}
}
func TestIsOddFullConvered(t *testing.T) {
list := make([]*IntRegion, 0, 8)
min, max := 1, 100
if IsOddFullConvered(list, min, max) {
t.Errorf("it's should be false, but now true-------1")
}
list = append(list, NewIntRegion(1, 10))
if IsOddFullConvered(list, min, max) == true {
t.Errorf("it's should be false, but now true-------2")
}
list = append(list, NewIntRegion(11, 100))
if IsOddFullConvered(list, min, max) == false {
t.Errorf("it's should be true, but now false-------1")
}
}
func TestIsDistinct_byte(t *testing.T) {
list := make([]byte, 0, 8)
result := IsDistinct_byte(list)
fmt.Printf("list:%v,result:%v-------1\n", list, result)
if result == false {
t.Errorf("it's should be true, but now false-------1")
}
list = append(list, 10)
result = IsDistinct_byte(list)
fmt.Printf("list:%v,result:%v-------2\n", list, result)
if result == false {
t.Errorf("it's should be true, but now false-------2")
}
list = append(list, 10)
result = IsDistinct_byte(list)
fmt.Printf("list:%v,result:%v-------3\n", list, result)
if result {
t.Errorf("it's should be false, but now true-------3")
}
list = append(list, 0)
result = IsDistinct_byte(list)
fmt.Printf("list:%v,result:%v-------4\n", list, result)
if result {
t.Errorf("it's should be false, but now true-------4")
}
}
func TestIsDistinct_int(t *testing.T) {
list := make([]int, 0, 8)
result := IsDistinct_int(list)
fmt.Printf("list:%v,result:%v-------1\n", list, result)
if result == false {
t.Errorf("it's should be true, but now false-------1")
}
list = append(list, 10)
result = IsDistinct_int(list)
fmt.Printf("list:%v,result:%v-------2\n", list, result)
if result == false {
t.Errorf("it's should be true, but now false-------2")
}
list = append(list, 10)
result = IsDistinct_int(list)
fmt.Printf("list:%v,result:%v-------3\n", list, result)
if result {
t.Errorf("it's should be false, but now true-------3")
}
list = append(list, 0)
result = IsDistinct_int(list)
fmt.Printf("list:%v,result:%v-------4\n", list, result)
if result {
t.Errorf("it's should be false, but now true-------4")
}
}
func TestIsDistinct_int32(t *testing.T) {
list := make([]int32, 0, 8)
result := IsDistinct_int32(list)
fmt.Printf("list:%v,result:%v-------1\n", list, result)
if result == false {
t.Errorf("it's should be true, but now false-------1")
}
list = append(list, 10)
result = IsDistinct_int32(list)
fmt.Printf("list:%v,result:%v-------2\n", list, result)
if result == false {
t.Errorf("it's should be true, but now false-------2")
}
list = append(list, 10)
result = IsDistinct_int32(list)
fmt.Printf("list:%v,result:%v-------3\n", list, result)
if result {
t.Errorf("it's should be false, but now true-------3")
}
list = append(list, 0)
result = IsDistinct_int32(list)
fmt.Printf("list:%v,result:%v-------4\n", list, result)
if result {
t.Errorf("it's should be false, but now true-------4")
}
}
func TestIsDistinct_int64(t *testing.T) {
list := make([]int64, 0, 8)
result := IsDistinct_int64(list)
fmt.Printf("list:%v,result:%v-------1\n", list, result)
if result == false {
t.Errorf("it's should be true, but now false-------1")
}
list = append(list, 10)
result = IsDistinct_int64(list)
fmt.Printf("list:%v,result:%v-------2\n", list, result)
if result == false {
t.Errorf("it's should be true, but now false-------2")
}
list = append(list, 10)
result = IsDistinct_int64(list)
fmt.Printf("list:%v,result:%v-------3\n", list, result)
if result {
t.Errorf("it's should be false, but now true-------3")
}
list = append(list, 0)
result = IsDistinct_int64(list)
fmt.Printf("list:%v,result:%v-------4\n", list, result)
if result {
t.Errorf("it's should be false, but now true-------4")
}
}

View File

@@ -0,0 +1,130 @@
package mathUtil
import (
"errors"
"math"
"sort"
)
//同时计算上中下四分位数
func Quartile_Int(intList []int) (lowerquartile, midquartile, upperquartile float64, err error) {
n := len(intList)
if n == 0 {
err = errors.New("List is empty")
return
}
//长度大于等于2的情况
//排序 升序
sort.Ints(intList)
lowerquartile, err = Quartile_Int_Lower(intList, true)
if err != nil {
return
}
midquartile, err = Quartile_Int_Mid(intList, true)
if err != nil {
return
}
upperquartile, err = Quartile_Int_Upper(intList, true)
if err != nil {
return
}
return
}
// 计算整数数组下四分为数据
func Quartile_Int_Lower(intList []int, isSorted bool) (lowerquartile float64, err error) {
n := len(intList)
if n == 0 {
err = errors.New("List is empty")
return
}
//如果长度为1则上、中、下四分为数都等于该值
if n == 1 {
lowerquartile = float64(intList[0])
return
}
//长度大于等于2的情况
//排序 升序 ,如果数据没有排序,则排序
if !isSorted {
sort.Ints(intList)
}
//计算下四分位数位置
lowerPosition := 1 + float64(n-1)*0.25
intPart, deciPart := math.Modf(lowerPosition)
//将整数部分转换为int类型成为取数据的索引
index := int(intPart)
if index < 1 || index > n-1 {
err = errors.New("Quartile_Int_Lower Index Out of Range")
return
}
lowerquartile = float64(intList[index-1])*(1-deciPart) + float64(intList[index])*deciPart
return
}
// 计算整数数组中四分为数据
func Quartile_Int_Mid(intList []int, isSorted bool) (midquartile float64, err error) {
n := len(intList)
if n == 0 {
err = errors.New("List is empty")
return
}
//如果长度为1则上、中、下四分为数都等于该值
if n == 1 {
midquartile = float64(intList[0])
return
}
//长度大于等于2的情况
//排序 升序 ,如果数据没有排序,则排序
if !isSorted {
sort.Ints(intList)
}
//计算下四分位数位置
lowerPosition := 1 + float64(n-1)*0.5
intPart, deciPart := math.Modf(lowerPosition)
//将整数部分转换为int类型成为取数据的索引
index := int(intPart)
if index < 1 || index > n-1 {
err = errors.New("Quartile_Int_Mid Index Out of Range")
return
}
midquartile = float64(intList[index-1])*(1-deciPart) + float64(intList[index])*deciPart
return
}
// 计算整数数组上四分为数据
func Quartile_Int_Upper(intList []int, isSorted bool) (upperquartile float64, err error) {
n := len(intList)
if n == 0 {
err = errors.New("List is empty")
return
}
//如果长度为1则上、中、下四分为数都等于该值
if n == 1 {
upperquartile = float64(intList[0])
return
}
//长度大于等于2的情况
//排序 升序 ,如果数据没有排序,则排序
if !isSorted {
sort.Ints(intList)
}
//计算下四分位数位置
lowerPosition := 1 + float64(n-1)*0.75
intPart, deciPart := math.Modf(lowerPosition)
//将整数部分转换为int类型成为取数据的索引
index := int(intPart)
if index < 1 || index > n-1 {
err = errors.New("Quartile_Int_Upper Index Out of Range")
return
}
upperquartile = float64(intList[index-1])*(1-deciPart) + float64(intList[index])*deciPart
return
}

View File

@@ -0,0 +1,53 @@
package mathUtil
import (
"fmt"
"testing"
)
func TestQuartile(t *testing.T) {
intList := []int{}
var lower, mid, upper float64
var err error
lower, mid, upper, err = Quartile_Int(intList)
if err != nil {
fmt.Printf("Error:%s\n", err)
}
intList = []int{4}
lower, mid, upper, err = Quartile_Int(intList)
if err != nil {
fmt.Printf("Error:%s\n", err)
}
fmt.Printf("LowerQuartile:%f\n", lower)
fmt.Printf("MidQuartile:%f\n", mid)
fmt.Printf("UpperQuartile:%f\n", upper)
intList = []int{4, 93}
lower, mid, upper, err = Quartile_Int(intList)
if err != nil {
fmt.Printf("Error:%s\n", err)
}
fmt.Printf("LowerQuartile:%f\n", lower)
fmt.Printf("MidQuartile:%f\n", mid)
fmt.Printf("UpperQuartile:%f\n", upper)
intList = []int{4, 93, 84}
lower, mid, upper, err = Quartile_Int(intList)
if err != nil {
fmt.Printf("Error:%s\n", err)
}
fmt.Printf("LowerQuartile:%f\n", lower)
fmt.Printf("MidQuartile:%f\n", mid)
fmt.Printf("UpperQuartile:%f\n", upper)
intList = []int{4, 93, 84, 85, 80, 37, 81, 93, 27, 12}
lower, mid, upper, err = Quartile_Int(intList)
if err != nil {
fmt.Printf("Error:%s\n", err)
}
fmt.Printf("LowerQuartile:%f\n", lower)
fmt.Printf("MidQuartile:%f\n", mid)
fmt.Printf("UpperQuartile:%f\n", upper)
}

View File

@@ -0,0 +1,479 @@
package mathUtil
import (
"errors"
"math/rand"
"time"
)
type Rand struct {
*rand.Rand
}
type weightRand struct {
index int
weight int
}
// 获得Rand对象(如果是循环生成多个数据,则只需要调用本方法一次,而不能调用多次,否则会得到相同的随机值)
func GetRand() *Rand {
return &Rand{
Rand: rand.New(rand.NewSource(time.Now().UnixNano())),
}
}
func GetRandInSeed(seed int64) *Rand {
return &Rand{
Rand: rand.New(rand.NewSource(seed)),
}
}
// 获取指定区间的随机数[lower, upper)
// lower:区间下限
// upper:区间上限
// 返回值:随机数
func (this *Rand) GetRandRangeInt(lower, upper int) int {
return lower + this.Intn(upper-lower)
}
// 获取指定区间的随机数[lower, upper)
// lower:区间下限
// upper:区间上限
// 返回值:随机数
func (this *Rand) GetRandRangeInt32(lower, upper int32) int32 {
return lower + this.Int31n(upper-lower)
}
// 获取指定区间的随机数[lower, upper)
// lower:区间下限
// upper:区间上限
// 返回值:随机数
func (this *Rand) GetRandRangeInt64(lower, upper int64) int64 {
return lower + this.Int63n(upper-lower)
}
// 获取随机数[0, n)
// randObj:随机对象
// n:范围上限
// 返回值:随机数
func (this *Rand) GetRandInt(n int) int {
return this.Intn(n)
}
// 获取随机数[0, n)
// n:范围上限
// 返回值:随机数
func (this *Rand) GetRandInt32(n int32) int32 {
return this.Int31n(n)
}
// 获取随机数[0, n)
// randObj:随机对象
// n:范围上限
// 返回值:随机数
func (this *Rand) GetRandInt64(n int64) int64 {
return this.Int63n(n)
}
// 获取随机数[0, 1)
// randObj:随机对象
// 返回值:随机数
func (this *Rand) GetRandFloat32() float32 {
return this.Float32()
}
// 获取随机数[0, 1)
// 返回值:随机数
func (this *Rand) GetRandFloat64() float64 {
return this.Float64()
}
// 获取随机数列表(取值范围:[minValue, maxValue]注意maxValue-minValue < 10000区间大小超过10000会抛出异常
// minValue:获取随机数的区间下限值
// maxValue:获取随机数的区间上限值
// count:随机数量
// ifAllowDuplicate:是否允许重复
// 返回值
// 随机数列表
func (this *Rand) GetRandNumList(minValue, maxValue, count int, ifAllowDuplicate bool) ([]int, error) {
if minValue > maxValue {
return nil, errors.New("minValue can't be bigger than maxValue.")
}
if !ifAllowDuplicate && (maxValue-minValue+1) < count {
return nil, errors.New("随机的数量超过区间的元素数量")
}
if (maxValue - minValue + 1) > 10000 {
return nil, errors.New("随机数的区间不能大于10000")
}
// 定义原始数据
sourceCount := maxValue - minValue + 1
source := make([]int, sourceCount, sourceCount)
for index := 0; index < sourceCount; index++ {
source[index] = minValue + index
}
// 定义返回值
resultList := make([]int, 0, count)
// 获取随机的索引列表
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
for _, index := range randIndextList {
// 判断是否已经取到足够数量的数据?
if count <= 0 {
break
}
resultList = append(resultList, source[index])
count -= 1
}
return resultList, nil
}
// 获取随机的int列表
// source:源列表
// count:随机数量
// ifAllowDuplicate:是否允许重复
// 返回值
// 随机数列表
func (this *Rand) GetRandIntList(source []int, count int, ifAllowDuplicate bool) ([]int, error) {
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
if ifAllowDuplicate == false && len(source) < count {
return nil, errors.New("随机的数量超过列表的元素数量")
}
// 定义返回值
resultList := make([]int, 0, count)
// 获取随机的索引列表
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
for _, index := range randIndextList {
// 判断是否已经取到足够数量的数据?
if count <= 0 {
break
}
resultList = append(resultList, source[index])
count -= 1
}
return resultList, nil
}
// 获取随机的int32列表
// source:源列表
// count:随机数量
// ifAllowDuplicate:是否允许重复
// 返回值
// 随机数列表
func (this *Rand) GetRandInt32List(source []int32, count int, ifAllowDuplicate bool) ([]int32, error) {
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
if ifAllowDuplicate == false && len(source) < count {
return nil, errors.New("随机的数量超过列表的元素数量")
}
// 定义返回值
resultList := make([]int32, 0, count)
// 获取随机的索引列表
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
for _, index := range randIndextList {
// 判断是否已经取到足够数量的数据?
if count <= 0 {
break
}
resultList = append(resultList, source[index])
count -= 1
}
return resultList, nil
}
// 获取随机的int64列表
// source:源列表
// count:随机数量
// ifAllowDuplicate:是否允许重复
// 返回值
// 随机数列表
func (this *Rand) GetRandInt64List(source []int64, count int, ifAllowDuplicate bool) ([]int64, error) {
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
if ifAllowDuplicate == false && len(source) < count {
return nil, errors.New("随机的数量超过列表的元素数量")
}
// 定义返回值
resultList := make([]int64, 0, count)
// 获取随机的索引列表
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
for _, index := range randIndextList {
// 判断是否已经取到足够数量的数据?
if count <= 0 {
break
}
resultList = append(resultList, source[index])
count -= 1
}
return resultList, nil
}
// 获取随机的int64列表
// source:源列表
// count:随机数量
// ifAllowDuplicate:是否允许重复
// 返回值
// 随机数列表
func (this *Rand) GetRandStringList(source []string, count int, ifAllowDuplicate bool) ([]string, error) {
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
if ifAllowDuplicate == false && len(source) < count {
return nil, errors.New("随机的数量超过列表的元素数量")
}
// 定义返回值
resultList := make([]string, 0, count)
// 获取随机的索引列表
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
for _, index := range randIndextList {
// 判断是否已经取到足够数量的数据?
if count <= 0 {
break
}
resultList = append(resultList, source[index])
count -= 1
}
return resultList, nil
}
// 获取随机的interface{}列表
// source:源列表
// count:随机数量
// ifAllowDuplicate:是否允许重复
// 返回值
// 随机数列表
func (this *Rand) GetRandInterfaceList(source []interface{}, count int, ifAllowDuplicate bool) ([]interface{}, error) {
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
if ifAllowDuplicate == false && len(source) < count {
return nil, errors.New("随机的数量超过列表的元素数量")
}
// 定义返回值
resultList := make([]interface{}, 0, count)
// 获取随机的索引列表
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
for _, index := range randIndextList {
// 判断是否已经取到足够数量的数据?
if count <= 0 {
break
}
resultList = append(resultList, source[index])
count -= 1
}
return resultList, nil
}
// 获取随机的索引列表
// count:数量
// ifAllowDuplicate:是否允许重复
// 返回值
// 随机索引值列表
func (this *Rand) getRandIndexList(maxNum, count int, ifAllowDuplicate bool) []int {
// 定义返回值
randIndextList := make([]int, 0, count)
// 使用源列表的数据量来初始化一个仅存放索引值的数组
indexList := make([]int, maxNum, maxNum)
for index := 0; index < maxNum; index++ {
indexList[index] = index
}
// 遍历列表并获取随机对象(通过不断缩小随机的范围来实现)
maxIndex := len(indexList) - 1
for {
if len(randIndextList) < count {
// 获取随机索引(由于Next方法不取上限值所以需要maxIndex+1)
randIndex := this.Intn(maxIndex + 1)
// 将数据添加到列表并增加findCount
randIndextList = append(randIndextList, indexList[randIndex])
// 如果不允许重复,则需要特殊处理
if !ifAllowDuplicate {
// 将该位置的数据和最大位置的数据进行交换
indexList[randIndex], indexList[maxIndex] = indexList[maxIndex], indexList[randIndex]
// 将随机的范围缩小
maxIndex -= 1
}
} else {
break
}
}
return randIndextList
}
// 获取带权重的随机数据
// source:源数据
// 返回值
// 数据项
// 错误对象
func (this *Rand) GetRandWeight(source []IWeight) (result IWeight, err error) {
if source == nil || len(source) == 0 {
err = errors.New("待随机的列表为空")
return
}
// 计算出总的数据量,并随机一个[0, total)的值
total := 0
for _, item := range source {
total += item.GetWeight()
}
randNum := this.GetRandInt(total)
// 根据随机出来的值,判断位于哪个区间
total = 0
for _, item := range source {
total += item.GetWeight()
if randNum < total {
result = item
return
}
}
err = errors.New("未找到有效的数据")
return
}
// 获取带权重的随机数据
// source:源数据
// count:返回数量
// ifAllowDuplicate返回索引中是否允许包含重复项
// 返回值
// 数据项的索引
// 错误对象
func (this *Rand) GetRandItemsByWeight(source []IWeight, count int, ifAllowDuplicate bool) ([]int, error) {
var err error
if source == nil || len(source) == 0 {
err = errors.New("待随机的列表为空")
return nil, err
}
if count <= 0 {
err = errors.New("count 必须大于0")
return nil, err
}
var lenCount int = len(source)
if lenCount < count && ifAllowDuplicate == false {
err = errors.New("source长度小于count并且设定为不可重复请修复")
return nil, err
}
// 准备数据
total := 0
weightList := make([]*weightRand, 0, lenCount)
for i, item := range source {
tempWeight := item.GetWeight()
weightList = append(weightList, &weightRand{index: i, weight: tempWeight})
total = total + tempWeight
}
if lenCount <= count {
return this.countLessThanRand(count, total, weightList), nil
}
return this.countIsGreaterThanRand(count, total, weightList), nil
}
// 获取带权重的随机数据(列表元素数量<=需要的数量)
// count:需要数量
// total:总权重
// weightList:权重列表
// 返回值
// 数据项的索引
func (this *Rand) countLessThanRand(count, total int, weightList []*weightRand) []int {
// 先所有的加入进去
result := make([]int, 0, count)
for k := range weightList {
result = append(result, k)
}
// 不删除随机
tempCount := len(result)
if tempCount >= count {
return result
}
for i := 0; i < count-tempCount; i++ {
tempk := -1
tempTotal := 0
tempRandNum := this.GetRandInt(total + 1)
for _, w := range weightList {
tempTotal = tempTotal + w.weight
if tempTotal > tempRandNum {
break
}
tempk = w.index
}
// 如果未找到,则取第一个
if tempk == -1 {
tempk = weightList[0].index
}
result = append(result, tempk)
}
return result
}
// 获取带权重的随机数据(列表元素数量>需要的数量)
// count:需要数量
// total:总权重
// weightList:权重列表
// 返回值
// 数据项的索引
func (this *Rand) countIsGreaterThanRand(count, total int, weightList []*weightRand) []int {
// 真随机+删除
result := make([]int, 0, count)
for j := 0; j < count; j++ {
tempTotal := 0
ri := -1
var tw *weightRand
tempRandNum := this.GetRandInt(total)
for i, v := range weightList {
tempTotal = tempTotal + v.weight
if tempTotal > tempRandNum {
break
}
tw = v
ri = i
}
// 如果未找到,则取第一个
if tw == nil {
tw = weightList[0]
ri = 0
}
result = append(result, tw.index)
total = total - tw.weight
// 删除已经随机过的item
weightList = append(weightList[:ri], weightList[ri+1:]...)
}
return result
}

View File

@@ -0,0 +1,325 @@
package mathUtil
import (
"fmt"
"testing"
)
func TestGetRandRangeInt(t *testing.T) {
lower, upper := 10, 100
rand := GetRand().GetRandRangeInt(lower, upper)
if rand < lower || rand >= upper {
t.Errorf("Expected a num between %d and %d, but got %d", lower, upper, rand)
}
}
func TestGetRandInt(t *testing.T) {
var n int = 100
var rand int = GetRand().GetRandInt(n)
if rand >= n {
t.Errorf("Expected a num < %d, but got %d", n, rand)
}
}
func TestGetRandInt32(t *testing.T) {
var n int32 = 100
var rand int32 = GetRand().GetRandInt32(n)
if rand >= n {
t.Errorf("Expected a num < %d, but got %d", n, rand)
}
}
func TestGetRandInt64(t *testing.T) {
var n int64 = 100
var rand int64 = GetRand().GetRandInt64(n)
if rand >= n {
t.Errorf("Expected a num < %d, but got %d", n, rand)
}
}
func TestGetRandFloat32(t *testing.T) {
var rand float32 = GetRand().GetRandFloat32()
if rand >= 1 {
t.Errorf("Expected a num < 1, but got %f", rand)
}
}
func TestGetRandFloat64(t *testing.T) {
var rand float64 = GetRand().GetRandFloat64()
if rand >= 1 {
t.Errorf("Expected a num < 1, but got %f", rand)
}
}
func TestGetRandNumList(t *testing.T) {
if _, err := GetRand().GetRandNumList(11, 10, 11, false); err.Error() != "minValue can't be bigger than maxValue." {
t.Error("Expected err, but got nil")
}
if _, err := GetRand().GetRandNumList(1, 10, 11, false); err.Error() != "随机的数量超过区间的元素数量" {
t.Error("Expected err, but got nil")
}
if _, err := GetRand().GetRandNumList(1, 10001, 10, false); err.Error() != "随机数的区间不能大于10000" {
t.Error("Expected err, but got nil")
}
randNumList, _ := GetRand().GetRandNumList(1, 10, 1, false)
fmt.Printf("randNumList:%v\n", randNumList)
randNumList, _ = GetRand().GetRandNumList(1, 10, 3, false)
fmt.Printf("randNumList:%v\n", randNumList)
randNumList, _ = GetRand().GetRandNumList(1, 10, 5, false)
fmt.Printf("randNumList:%v\n", randNumList)
randNumList, _ = GetRand().GetRandNumList(1, 10, 7, false)
fmt.Printf("randNumList:%v\n", randNumList)
randNumList, _ = GetRand().GetRandNumList(1, 10, 9, false)
fmt.Printf("randNumList:%v\n", randNumList)
randNumList, _ = GetRand().GetRandNumList(1, 10, 11, true)
fmt.Printf("randNumList:%v\n", randNumList)
}
func TestGetRandIntList(t *testing.T) {
source := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
if _, err := GetRand().GetRandIntList(source, 11, false); err.Error() != "随机的数量超过列表的元素数量" {
t.Error("Expected err, but got nil")
}
randIntList, _ := GetRand().GetRandIntList(source, 1, false)
fmt.Printf("randIntList:%v\n", randIntList)
randIntList, _ = GetRand().GetRandIntList(source, 3, false)
fmt.Printf("randIntList:%v\n", randIntList)
randIntList, _ = GetRand().GetRandIntList(source, 5, false)
fmt.Printf("randIntList:%v\n", randIntList)
randIntList, _ = GetRand().GetRandIntList(source, 7, false)
fmt.Printf("randIntList:%v\n", randIntList)
randIntList, _ = GetRand().GetRandIntList(source, 9, false)
fmt.Printf("randIntList:%v\n", randIntList)
randIntList, _ = GetRand().GetRandIntList(source, 10, true)
fmt.Printf("randIntList:%v\n", randIntList)
}
func TestGetRandInterfaceList(t *testing.T) {
item1 := NewItem(1, "name1", 1)
item2 := NewItem(2, "name1", 1)
item3 := NewItem(3, "name1", 1)
item4 := NewItem(4, "name1", 1)
item5 := NewItem(5, "name1", 1)
item6 := NewItem(6, "name1", 1)
item7 := NewItem(7, "name1", 1)
item8 := NewItem(8, "name1", 1)
item9 := NewItem(9, "name1", 1)
item10 := NewItem(10, "name1", 1)
source := make([]interface{}, 0, 10)
source = append(source, item1)
source = append(source, item2)
source = append(source, item3)
source = append(source, item4)
source = append(source, item5)
source = append(source, item6)
source = append(source, item7)
source = append(source, item8)
source = append(source, item9)
source = append(source, item10)
if _, err := GetRand().GetRandInterfaceList(source, 11, false); err.Error() != "随机的数量超过列表的元素数量" {
t.Error("Expected err, but got nil")
}
randInterfaceList, _ := GetRand().GetRandInterfaceList(source, 1, false)
fmt.Printf("randInterfaceList:%v\n", randInterfaceList)
randInterfaceList, _ = GetRand().GetRandInterfaceList(source, 3, false)
fmt.Printf("randInterfaceList:%v\n", randInterfaceList)
randInterfaceList, _ = GetRand().GetRandInterfaceList(source, 5, false)
fmt.Printf("randInterfaceList:%v\n", randInterfaceList)
randInterfaceList, _ = GetRand().GetRandInterfaceList(source, 7, false)
fmt.Printf("randInterfaceList:%v\n", randInterfaceList)
randInterfaceList, _ = GetRand().GetRandInterfaceList(source, 9, false)
fmt.Printf("randInterfaceList:%v\n", randInterfaceList)
randInterfaceList, _ = GetRand().GetRandInterfaceList(source, 10, true)
fmt.Printf("randInterfaceList:%v\n", randInterfaceList)
}
func TestGetRandWeight(t *testing.T) {
source := make([]IWeight, 0, 10)
if _, err := GetRand().GetRandWeight(source); err == nil {
t.Errorf("err should not be nil, but it's nil")
}
item1 := NewItem(1, "name1", 1)
item2 := NewItem(2, "name2", 2)
item3 := NewItem(3, "name3", 3)
item4 := NewItem(4, "name4", 4)
item5 := NewItem(5, "name5", 5)
item6 := NewItem(6, "name6", 60)
item7 := NewItem(7, "name7", 70)
item8 := NewItem(8, "name8", 80)
item9 := NewItem(9, "name9", 90)
item10 := NewItem(10, "name10", 100)
source = append(source, item1)
source = append(source, item2)
source = append(source, item3)
source = append(source, item4)
source = append(source, item5)
source = append(source, item6)
source = append(source, item7)
source = append(source, item8)
source = append(source, item9)
source = append(source, item10)
data := make(map[int]int)
for i := 0; i < 10000; i++ {
if result, err := GetRand().GetRandWeight(source); err != nil {
t.Errorf("err should be nil, but it's not:%s", err)
} else {
if item, ok := result.(*Item); !ok {
t.Errorf("convert to Item failed")
} else {
if count, ok := data[item.Id]; ok {
data[item.Id] = count + 1
} else {
data[item.Id] = 1
}
}
}
}
total := 0
for _, v := range data {
total += v
}
k := 1
if v, ok := data[k]; ok {
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
}
k = 2
if v, ok := data[k]; ok {
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
}
k = 3
if v, ok := data[k]; ok {
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
}
k = 4
if v, ok := data[k]; ok {
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
}
k = 5
if v, ok := data[k]; ok {
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
}
k = 6
if v, ok := data[k]; ok {
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
}
k = 7
if v, ok := data[k]; ok {
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
}
k = 8
if v, ok := data[k]; ok {
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
}
k = 9
if v, ok := data[k]; ok {
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
}
k = 10
if v, ok := data[k]; ok {
fmt.Printf("%d:%d, ratio:%d\n", k, v, v*100/total)
}
}
func TestGetRandWeight2(t *testing.T) {
source := make([]IWeight, 0, 10)
if _, err := GetRand().GetRandWeight(source); err == nil {
t.Errorf("err should not be nil, but it's nil")
}
item1 := NewItem(1, "name1", 1)
item2 := NewItem(2, "name2", 2)
item3 := NewItem(3, "name3", 3)
item4 := NewItem(4, "name4", 4)
item5 := NewItem(5, "name5", 5)
item6 := NewItem(6, "name6", 60)
item7 := NewItem(7, "name7", 70)
item8 := NewItem(8, "name8", 80)
item9 := NewItem(9, "name9", 90)
item10 := NewItem(10, "name10", 100)
source = append(source, item1)
source = append(source, item2)
source = append(source, item3)
source = append(source, item4)
source = append(source, item5)
source = append(source, item6)
source = append(source, item7)
source = append(source, item8)
source = append(source, item9)
source = append(source, item10)
rindexs, err := GetRand().GetRandItemsByWeight(source, 2, false)
if err != nil {
t.Errorf("GetRandItemsByWeight出错:%s", err)
}
if len(rindexs) != 2 || rindexs[0] == rindexs[1] {
t.Errorf("GetRandItemsByWeight随机内容出错")
}
rindexs, err = GetRand().GetRandItemsByWeight(source, 10, false)
if err != nil {
t.Errorf("GetRandItemsByWeight出错:%s", err)
}
if len(rindexs) != 10 {
t.Errorf("GetRandItemsByWeight随机内容出错")
}
_, err = GetRand().GetRandItemsByWeight(source, 12, false)
if err == nil {
t.Errorf("GetRandItemsByWeight出错:%s", err)
}
rindexs, err = GetRand().GetRandItemsByWeight(source, 15, true)
if err != nil {
t.Errorf("GetRandItemsByWeight出错:%s", err)
}
if len(rindexs) != 15 {
t.Errorf("GetRandItemsByWeight随机内容出错")
}
}
type Item struct {
Id int
Name string
Weight int
}
func (item *Item) GetWeight() int {
return item.Weight
}
func (item *Item) String() string {
return fmt.Sprintf("Id:%d,Name:%s\n", item.Id, item.Name)
}
func NewItem(id int, name string, weight int) *Item {
return &Item{
Id: id,
Name: name,
Weight: weight,
}
}
func Test_GetRandom(t *testing.T) {
rand, err := GetRand().GetRandNumList(1, 10000, 10, true)
if err != nil {
t.Log(fmt.Errorf("获取随机数错误:%s", err))
}
t.Log(rand)
}

View File

@@ -0,0 +1,381 @@
package mathUtil
import (
"errors"
"math/rand"
"sync"
"time"
)
//SafeRand 安全的随机
type SafeRand struct {
*rand.Rand
mu sync.Mutex
}
func GetSafeRand() *SafeRand {
return &SafeRand{
Rand: rand.New(rand.NewSource(time.Now().UnixNano())),
}
}
func GetSafeRandInSeed(seed int64) *SafeRand {
return &SafeRand{
Rand: rand.New(rand.NewSource(seed)),
}
}
func (this *SafeRand) Int() int {
this.mu.Lock()
defer this.mu.Unlock()
return this.Rand.Int()
}
func (this *SafeRand) Intn(n int) int {
this.mu.Lock()
defer this.mu.Unlock()
return this.Rand.Intn(n)
}
func (this *SafeRand) Int31() int32 {
this.mu.Lock()
defer this.mu.Unlock()
return this.Rand.Int31()
}
func (this *SafeRand) Int31n(n int32) int32 {
this.mu.Lock()
defer this.mu.Unlock()
return this.Rand.Int31n(n)
}
func (this *SafeRand) Int63() int64 {
this.mu.Lock()
defer this.mu.Unlock()
return this.Rand.Int63()
}
func (this *SafeRand) Int63n(n int64) int64 {
this.mu.Lock()
defer this.mu.Unlock()
return this.Rand.Int63n(n)
}
func (this *SafeRand) Float64() float64 {
this.mu.Lock()
defer this.mu.Unlock()
return this.Rand.Float64()
}
func (this *SafeRand) Float32() float32 {
this.mu.Lock()
defer this.mu.Unlock()
return this.Rand.Float32()
}
// 获取指定区间的随机数[lower, upper)
// lower:区间下限
// upper:区间上限
// 返回值:随机数
func (this *SafeRand) GetRandRangeInt(lower, upper int) int {
return lower + this.Intn(upper-lower)
}
// 获取指定区间的随机数[lower, upper)
// lower:区间下限
// upper:区间上限
// 返回值:随机数
func (this *SafeRand) GetRandRangeInt32(lower, upper int32) int32 {
return lower + this.Int31n(upper-lower)
}
// 获取指定区间的随机数[lower, upper)
// lower:区间下限
// upper:区间上限
// 返回值:随机数
func (this *SafeRand) GetRandRangeInt64(lower, upper int64) int64 {
return lower + this.Int63n(upper-lower)
}
// 获取随机数[0, n)
// randObj:随机对象
// n:范围上限
// 返回值:随机数
func (this *SafeRand) GetRandInt(n int) int {
return this.Intn(n)
}
// 获取随机数[0, n)
// n:范围上限
// 返回值:随机数
func (this *SafeRand) GetRandInt32(n int32) int32 {
return this.Int31n(n)
}
// 获取随机数[0, n)
// randObj:随机对象
// n:范围上限
// 返回值:随机数
func (this *SafeRand) GetRandInt64(n int64) int64 {
return this.Int63n(n)
}
// 获取随机数[0, 1)
// randObj:随机对象
// 返回值:随机数
func (this *SafeRand) GetRandFloat32() float32 {
return this.Float32()
}
// 获取随机数[0, 1)
// 返回值:随机数
func (this *SafeRand) GetRandFloat64() float64 {
return this.Float64()
}
// 获取随机数列表1~10000超过10000会抛出异常
// minValue:获取随机数的区间下限值
// maxValue:获取随机数的区间上限值
// count:随机数量
// ifAllowDuplicate:是否允许重复
// 返回值
// 随机数列表
func (this *SafeRand) GetRandNumList(minValue, maxValue, count int, ifAllowDuplicate bool) ([]int, error) {
if minValue > maxValue {
return nil, errors.New("minValue can't be bigger than maxValue.")
}
if !ifAllowDuplicate && (maxValue-minValue+1) < count {
return nil, errors.New("随机的数量超过区间的元素数量")
}
if (maxValue - minValue + 1) > 10000 {
return nil, errors.New("随机数的区间不能大于10000")
}
// 定义原始数据
sourceCount := maxValue - minValue + 1
source := make([]int, sourceCount, sourceCount)
for index := 0; index < sourceCount; index++ {
source[index] = minValue + index
}
// 定义返回值
resultList := make([]int, 0, count)
// 获取随机的索引列表
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
for _, index := range randIndextList {
// 判断是否已经取到足够数量的数据?
if count <= 0 {
break
}
resultList = append(resultList, source[index])
count -= 1
}
return resultList, nil
}
// 获取随机的int列表
// source:源列表
// count:随机数量
// ifAllowDuplicate:是否允许重复
// 返回值
// 随机数列表
func (this *SafeRand) GetRandIntList(source []int, count int, ifAllowDuplicate bool) ([]int, error) {
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
if ifAllowDuplicate == false && len(source) < count {
return nil, errors.New("随机的数量超过列表的元素数量")
}
// 定义返回值
resultList := make([]int, 0, count)
// 获取随机的索引列表
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
for _, index := range randIndextList {
// 判断是否已经取到足够数量的数据?
if count <= 0 {
break
}
resultList = append(resultList, source[index])
count -= 1
}
return resultList, nil
}
// 获取随机的int32列表
// source:源列表
// count:随机数量
// ifAllowDuplicate:是否允许重复
// 返回值
// 随机数列表
func (this *SafeRand) GetRandInt32List(source []int32, count int, ifAllowDuplicate bool) ([]int32, error) {
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
if ifAllowDuplicate == false && len(source) < count {
return nil, errors.New("随机的数量超过列表的元素数量")
}
// 定义返回值
resultList := make([]int32, 0, count)
// 获取随机的索引列表
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
for _, index := range randIndextList {
// 判断是否已经取到足够数量的数据?
if count <= 0 {
break
}
resultList = append(resultList, source[index])
count -= 1
}
return resultList, nil
}
// 获取随机的int64列表
// source:源列表
// count:随机数量
// ifAllowDuplicate:是否允许重复
// 返回值
// 随机数列表
func (this *SafeRand) GetRandInt64List(source []int64, count int, ifAllowDuplicate bool) ([]int64, error) {
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
if ifAllowDuplicate == false && len(source) < count {
return nil, errors.New("随机的数量超过列表的元素数量")
}
// 定义返回值
resultList := make([]int64, 0, count)
// 获取随机的索引列表
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
for _, index := range randIndextList {
// 判断是否已经取到足够数量的数据?
if count <= 0 {
break
}
resultList = append(resultList, source[index])
count -= 1
}
return resultList, nil
}
// 获取随机的interface{}列表
// source:源列表
// count:随机数量
// ifAllowDuplicate:是否允许重复
// 返回值
// 随机数列表
func (this *SafeRand) GetRandInterfaceList(source []interface{}, count int, ifAllowDuplicate bool) ([]interface{}, error) {
// 在不允许重复的情况下,需要产生的随机数不能超过范围限制
if ifAllowDuplicate == false && len(source) < count {
return nil, errors.New("随机的数量超过列表的元素数量")
}
// 定义返回值
resultList := make([]interface{}, 0, count)
// 获取随机的索引列表
randIndextList := this.getRandIndexList(len(source), count, ifAllowDuplicate)
for _, index := range randIndextList {
// 判断是否已经取到足够数量的数据?
if count <= 0 {
break
}
resultList = append(resultList, source[index])
count -= 1
}
return resultList, nil
}
// 获取随机的索引列表
// count:数量
// ifAllowDuplicate:是否允许重复
// 返回值
// 随机索引值列表
func (this *SafeRand) getRandIndexList(maxNum, count int, ifAllowDuplicate bool) []int {
// 定义返回值
randIndextList := make([]int, 0, count)
// 使用源列表的数据量来初始化一个仅存放索引值的数组
indexList := make([]int, maxNum, maxNum)
for index := 0; index < maxNum; index++ {
indexList[index] = index
}
// 遍历列表并获取随机对象(通过不断缩小随机的范围来实现)
maxIndex := len(indexList) - 1
for {
if len(randIndextList) < count {
// 获取随机索引(由于Next方法不取上限值所以需要maxIndex+1)
randIndex := this.Intn(maxIndex + 1)
// 将数据添加到列表并增加findCount
randIndextList = append(randIndextList, indexList[randIndex])
// 如果不允许重复,则需要特殊处理
if !ifAllowDuplicate {
// 将该位置的数据和最大位置的数据进行交换
indexList[randIndex], indexList[maxIndex] = indexList[maxIndex], indexList[randIndex]
// 将随机的范围缩小
maxIndex -= 1
}
} else {
break
}
}
return randIndextList
}
// 获取带权重的随机数据
// source:源数据
// 返回值
// 数据项
// 错误对象
func (this *SafeRand) GetRandWeight(source []IWeight) (result IWeight, err error) {
if source == nil || len(source) == 0 {
err = errors.New("待随机的列表为空")
return
}
// 计算出总的数据量,并随机一个[0, total)的值
total := 0
for _, item := range source {
total += item.GetWeight()
}
randNum := this.GetRandInt(total)
// 根据随机出来的值,判断位于哪个区间
total = 0
for _, item := range source {
total += item.GetWeight()
if randNum < total {
result = item
return
}
}
err = errors.New("未找到有效的数据")
return
}

View File

@@ -0,0 +1,47 @@
package mathUtil
import (
"testing"
)
func TestGetSafeRandProccess(t *testing.T) {
// r := GetSafeRand()
// for {
// go r.Int()
// go r.Intn(10)
// go r.Int31()
// go r.Int31n(10)
// go r.Int63()
// go r.Int63n(10)
// go r.Float64()
// go r.Float32()
// }
// r1 := GetRand()
// for {
// go r1.Int()
// }
}
func BenchmarkInt(b *testing.B) {
r := GetSafeRand()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
r.Int()
}
})
}
func BenchmarkGetRandNumList(b *testing.B) {
r := GetSafeRand()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_, err := r.GetRandNumList(1, 10000, 10, true)
if err != nil {
b.Error(err)
}
}
})
}

View File

@@ -0,0 +1,37 @@
package mathUtil
import (
"fmt"
)
// 获取字节大小的描述信息
// size字节大小
// 返回值:
// 描述信息
func GetSizeDesc(size int64) string {
str := ""
// 判断输入是否超过int64的范围
if size < 0 || size > (1<<63-1) {
return str
}
switch {
case size >= 1024*1024*1024*1024*1024*1024:
str = fmt.Sprintf("%.2fEB", float64(size)/1024/1024/1024/1024/1024/1024)
case size >= 1024*1024*1024*1024*1024:
str = fmt.Sprintf("%.2fPB", float64(size)/1024/1024/1024/1024/1024)
case size >= 1024*1024*1024*1024:
str = fmt.Sprintf("%.2fTB", float64(size)/1024/1024/1024/1024)
case size >= 1024*1024*1024:
str = fmt.Sprintf("%.2fGB", float64(size)/1024/1024/1024)
case size >= 1024*1024:
str = fmt.Sprintf("%dMB", size/1024/1024)
case size >= 1024:
str = fmt.Sprintf("%dKB", size/1024)
default:
str = fmt.Sprintf("%dB", size)
}
return str
}

View File

@@ -0,0 +1,61 @@
package mathUtil
import (
"testing"
)
func TestGetSizeDesc(t *testing.T) {
var size int64
var expectedStr string
var finalStr string
size = 1
expectedStr = "1B"
finalStr = GetSizeDesc(size)
if finalStr != expectedStr {
t.Errorf("Expected %s, but got %s", expectedStr, finalStr)
}
size *= 1024
expectedStr = "1KB"
finalStr = GetSizeDesc(size)
if finalStr != expectedStr {
t.Errorf("Expected %s, but got %s", expectedStr, finalStr)
}
size *= 1024
expectedStr = "1MB"
finalStr = GetSizeDesc(size)
if finalStr != expectedStr {
t.Errorf("Expected %s, but got %s", expectedStr, finalStr)
}
size *= 1024
expectedStr = "1.00GB"
finalStr = GetSizeDesc(size)
if finalStr != expectedStr {
t.Errorf("Expected %s, but got %s", expectedStr, finalStr)
}
size *= 1024
expectedStr = "1.00TB"
finalStr = GetSizeDesc(size)
if finalStr != expectedStr {
t.Errorf("Expected %s, but got %s", expectedStr, finalStr)
}
size *= 1024
expectedStr = "1.00PB"
finalStr = GetSizeDesc(size)
if finalStr != expectedStr {
t.Errorf("Expected %s, but got %s", expectedStr, finalStr)
}
size *= 1024
expectedStr = "1.00EB"
finalStr = GetSizeDesc(size)
if finalStr != expectedStr {
t.Errorf("Expected %s, but got %s", expectedStr, finalStr)
}
}