[Go] 判断字符串是否在切片中踩的坑

因为业务需要,写了一个判断字符串是否在切片中的函数,代码如下:

func InStrSlice(target string , str_arr []string) bool {
	sort.Strings(str_arr)
	index := sort.SearchStrings(str_arr, target)
	if index < len(str_arr) && str_arr[index] == target {
		return true
	}
	return false
}

func main() {
	strs := []string{"b", "c", "a", "e", "f", "d"}
	fmt.Println("目标切片:", strs)
	fmt.Println("待检查的字符串:", "a", "  判断结果:", InStrSlice("a", strs))
	fmt.Println("待检查的字符串:", "h", "  判断结果:", InStrSlice("h", strs))
	fmt.Println("目标切片当前状态:", strs)
}

看起来好像没什么问题,也能达到我的预期目的,执行结果如下:

发现问题了吗?是的,原始切片的顺序被改变了,这并不是我想要的结果!看来直接使用传递过来的切片,是地址传递,所以会改变外部的切片。

我第一时间就想到重新生成一个切片,避免影响到原来的,改进后的代码:

func InStrSlice(target string , str_arr []string) bool {
    temp := make([]string, len(str_array))
  	copy(temp,str_arr)
	sort.Strings(temp)
	index := sort.SearchStrings(temp, target)
	if index < len(temp) && temp[index] == target {
		return true
	}
	return false
}

重新执行,问题解决:

注意,copy的时候,临时切片需要声明长度,不然会copy不成功,copy的长度与你声明的长度有关

[Go]红包算法-二倍均值算法

100块钱随机发红包,怎样才能公平
假设剩余红包金额m元,剩余人数n人。那么有如下公式
每次抢到的金额=随机区间[0.01,m/n2-0.01]元
举个例子
100/52=40元。 所以第一个人抢到的金额范围在0.01-39.99元。
第二个人 80/4*2 所以第二个人抢到的金额范围在0.01-39.99元
所以,每个人抢到的范围均值是相等的

// DoubleAverage 二倍均值算法
func DoubleAverage(count, amount int64) int64 {
	if count == 1 {
		return amount
	}
	//计算出最大可用金额
	max := amount - min*count
	//计算最大可用平均值
	avg := max / count
	//二倍均值基础在加上最小金额 防止出现0值
	avg2 := 2*avg + min
	//随机红包金额序列元素,把二倍均值作为随机的最大数
	rand.Seed(time.Now().UnixNano())
	randNum := rand.Int63n(avg2)
	x := randNum + min
	fmt.Printf("剩余人数:%d\t抢到:%.2f \t剩余金额:%.2f\t本次均值的二倍:%.2f\t金额随机范围:[%0.2f, %.2f]\n",
		count, float64(x)/100, float64(amount-x)/100, float64(avg2)/100, float64(min)/100, float64(randNum)/100)
	return x
}

运行结果: