1. 并发100个任务,但是同一时间最多运行的10个任务
利用channel缓冲管道队列满了需要等待,其他goroutine读取消息释放特性
func init() {
count := 10
num := 1000
wg := sync.WaitGroup{}
c := make(chan struct{}, count)
for i := 0; i < num; i++ {
wg.Add(1)
c <- struct{}{}
go func(j int) {
defer wg.Done()
fmt.Println(j)
<-c
time.Sleep(time.Second * 10)
}(i)
}
wg.Wait()
}
2. 青蛙跳台阶,总共5个台阶可以一次1步或者2步,跳上去有几种跳法
利用斐波那契算法
func main() {
n := 5 // 台阶数
ways := climbStairs(n)
fmt.Printf("对于 %d 阶台阶,共有 %d 种上法\n", n, ways)
}
func climbStairs(n int) int {
if n <= 1 {
return 1
}
if n == 2 {
return 2
}
// if n == 3 {
// return 4
// }
return climbStairs(n-1) + climbStairs(n-2)
}
func climbStairs2(n int) int {
if n <= 1 {
return 1
}
dp := make([]int, n+1)
dp[0] = 1
dp[1] = 1
for i := 2; i <= n; i++ {
dp[i] = dp[i-1] + dp[i-2]
}
fmt.Println(dp)
return dp[n]
}
3. 给出一个数字在map数组中找到最相近的数字
// 给出一个数字在map数组中找到最相近的数字
func solution(ranks map[int]int, ho int) int {
ranks[1] = 93
ranks[10] = 55
ranks[15] = 30
ranks[20] = 19
ranks[23] = 11
ranks[30] = 2
gap := 0
prevGap := 0
result := 0
for rank, honor := range ranks {
gap = int(math.Abs(float64(honor - ho)))
if gap <= prevGap {
result = rank
}
prevGap = gap
}
return result
}
4. 输入4个数字和一个期望值,通过加减乘除,算出期望值
算法有优化的地方欢迎讨论
package main
import (
"fmt"
"strconv"
"strings"
)
// 用golang写一个方法,输入4个数字和一个期望值,通过加减乘除,算出期望值
func main() {
input := []int{2, 2, 5, 4}
target := 24
calculate(input, target)
}
func calculate(input []int, target int) (bool, string) {
// 定义运算符组合
operators := []string{"+", "-", "*", "/"}
num1, num2, num3, num4 := input[0], input[1], input[2], input[3]
// 遍历所有可能的运算符组合
for _, op1 := range operators {
for _, op2 := range operators {
for _, op3 := range operators {
// 构建表达式
expression := fmt.Sprintf("%d %s %d %s %d %s %d", num1, op1, num2, op2, num3, op3, num4)
// 计算表达式结果
result := eval(expression)
// 判断计算结果是否等于期望值
if result == float64(target) {
fmt.Println(expression, "=", target)
return true, expression
}
}
}
}
return false, ""
}
func eval(expression string) float64 {
// 将表达式字符串按空格分隔成切片
tokens := strings.Split(expression, " ")
// 优化:先计算乘法和除法
for i := 1; i < len(tokens); i += 2 {
operator := tokens[i]
if operator == "*" || operator == "/" {
operand1, _ := strconv.ParseFloat(tokens[i-1], 64)
operand2, _ := strconv.ParseFloat(tokens[i+1], 64)
var result float64
switch operator {
case "*":
result = operand1 * operand2
case "/":
if operand2 == 0 {
return 0
}
result = operand1 / operand2
}
// 替换乘法和除法的部分为计算结果
tokens[i-1] = strconv.FormatFloat(result, 'f', -1, 64)
// 移除乘法和除法的部分
tokens = append(tokens[:i], tokens[i+2:]...)
i -= 2 // 调整索引,继续循环
}
}
// 初始化结果为第一个数字
result, err := strconv.ParseFloat(tokens[0], 64)
if err != nil {
return 0
}
// 遍历剩余的运算符和数字,依次计算表达式
for i := 1; i < len(tokens); i += 2 {
operator := tokens[i]
operand, err := strconv.ParseFloat(tokens[i+1], 64)
if err != nil {
return 0
}
// 根据运算符进行相应的计算
switch operator {
case "+":
result += operand
case "-":
result -= operand
}
}
fmt.Printf("%s ====> %#v ====> %f \r\n", expression, tokens, result)
return result
}