探索Go语言中的随机数生成、矩阵运算与数独验证

1. Go中的随机数生成

在许多编程任务中,随机数的生成是不可或缺的。Go语言通过 math/rand 包提供了伪随机数生成方式。伪随机数由种子(seed)决定,如果种子相同,生成的数列也会相同。为了确保每次程序运行时产生不同的随机数,我们通常使用当前时间作为种子。

示例1:简单的随机数生成
go 复制代码
package main

import (
	"fmt"
	"math/rand"
	"time"
)

func random(min, max int) int {
	return rand.Intn(max-min) + min
}

func main() {
	rand.Seed(time.Now().Unix())
	for i := 0; i < 5; i++ {
		fmt.Println("生成的随机数:", random(0, 100))
	}
}

上述程序使用了当前时间作为种子来生成0到100之间的5个随机数。输出结果每次都会不同。

示例2:通过命令行控制随机数生成

为了使程序更具灵活性,我们可以通过命令行传入参数来控制随机数的生成范围和数量,甚至可以指定种子来生成固定序列的伪随机数。

go 复制代码
package main

import (
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"time"
)

func random(min, max int) int {
	return rand.Intn(max-min) + min
}

func main() {
	MIN := 0
	MAX := 100
	TOTAL := 10
	SEED := time.Now().Unix()
	arguments := os.Args

	switch len(arguments) {
	case 2:
		MIN, _ = strconv.Atoi(arguments[1])
		MAX = MIN + 100
	case 3:
		MIN, _ = strconv.Atoi(arguments[1])
		MAX, _ = strconv.Atoi(arguments[2])
	case 4:
		MIN, _ = strconv.Atoi(arguments[1])
		MAX, _ = strconv.Atoi(arguments[2])
		TOTAL, _ = strconv.Atoi(arguments[3])
	case 5:
		MIN, _ = strconv.Atoi(arguments[1])
		MAX, _ = strconv.Atoi(arguments[2])
		TOTAL, _ = strconv.Atoi(arguments[3])
		SEED, _ = strconv.ParseInt(arguments[4], 10, 64)
	default:
		fmt.Println("使用默认值")
	}

	rand.Seed(SEED)

	for i := 0; i < TOTAL; i++ {
		fmt.Printf("%d ", random(MIN, MAX))
	}
	fmt.Println()
}

通过不同的命令行参数,可以控制生成的随机数。例如:

bash 复制代码
$ go run randomNumbers.go 10 50 5
14 37 27 49 16

这段代码生成了5个在10到50之间的随机数。

2. 加密级别的随机数生成

在安全领域,生成密码时,伪随机数不足以提供安全性。Go提供了 crypto/rand 包来生成加密安全的随机数,它可以生成不可预测的随机序列。

示例3:生成加密安全的随机密码
go 复制代码
package main

import (
	"crypto/rand"
	"encoding/base64"
	"fmt"
	"os"
	"strconv"
)

func generateBytes(n int64) ([]byte, error) {
	b := make([]byte, n)
	_, err := rand.Read(b)
	if err != nil {
		return nil, err
	}
	return b, nil
}

func generatePass(s int64) (string, error) {
	b, err := generateBytes(s)
	return base64.URLEncoding.EncodeToString(b), err
}

func main() {
	var LENGTH int64 = 8
	arguments := os.Args

	if len(arguments) == 2 {
		LENGTH, _ = strconv.ParseInt(arguments[1], 10, 64)
	}

	myPass, err := generatePass(LENGTH)
	if err != nil {
		fmt.Println("生成密码失败:", err)
		return
	}

	fmt.Println("生成的密码:", myPass[0:LENGTH])
}

运行程序后会生成一个随机密码,例如:

生成的密码: Zm9yQ29kZT==

3. 矩阵运算与生成

矩阵在图像处理、机器学习等领域中有广泛应用。我们可以利用Go语言生成随机矩阵,并进行矩阵加法、减法等运算。

示例4:生成随机矩阵并进行矩阵加法
go 复制代码
package main

import (
	"fmt"
	"math/rand"
	"time"
)

func generateMatrix(row, col int) [][]int {
	matrix := make([][]int, row)
	for i := range matrix {
		matrix[i] = make([]int, col)
		for j := range matrix[i] {
			matrix[i][j] = rand.Intn(10)
		}
	}
	return matrix
}

func addMatrices(m1, m2 [][]int) [][]int {
	result := make([][]int, len(m1))
	for i := range m1 {
		result[i] = make([]int, len(m1[i]))
		for j := range m1[i] {
			result[i][j] = m1[i][j] + m2[i][j]
		}
	}
	return result
}

func main() {
	rand.Seed(time.Now().Unix())

	m1 := generateMatrix(3, 3)
	m2 := generateMatrix(3, 3)

	fmt.Println("矩阵1:", m1)
	fmt.Println("矩阵2:", m2)

	result := addMatrices(m1, m2)
	fmt.Println("矩阵加法结果:", result)
}

通过上述代码,您可以生成两个3x3的随机矩阵,并执行矩阵加法运算。

4. 数独验证程序

数独是一个流行的逻辑益智游戏,要求将1到9填入一个9x9的网格中,使每行、每列和每个3x3的子区域都包含不重复的数字。我们可以通过编写程序验证数独是否解得正确。

示例5:数独验证
go 复制代码
package main

import (
	"bufio"
	"errors"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func importFile(file string) ([][]int, error) {
	var err error
	var mySlice = make([][]int, 0)
	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	r := bufio.NewReader(f)
	for {
		line, err := r.ReadString('\n')
		fields := strings.Fields(line)
		temp := make([]int, 0)
		for _, v := range fields {
			n, err := strconv.Atoi(v)
			if err != nil {
				return nil, err
			}
			temp = append(temp, n)
		}
		if len(temp) != 0 {
			mySlice = append(mySlice, temp)
		}
		if err != nil {
			break
		}
	}
	return mySlice, nil
}

func validPuzzle(sl [][]int) bool {
	for i := 0; i <= 2; i++ {
		for j := 0; j <= 2; j++ {
			iEl := i * 3
			jEl := j * 3
			mySlice := []int{0, 0, 0, 0, 0, 0, 0, 0, 0}
			for k := 0; k <= 2; k++ {
				for m := 0; m <= 2; m++ {
					bigI := iEl + k
					bigJ := jEl + m
					val := sl[bigI][bigJ]
					if val > 0 && val < 10 {
						if mySlice[val-1] == 1 {
							fmt.Println("数字出现两次:", val)
							return false
						} else {
							mySlice[val-1] = 1
						}
					} else {
						fmt.Println("无效值:", val)
						return false
					}
				}
			}
		}
	}

	for i := 0; i <= 8; i++ {
		sum := 0
		for j := 0; j <= 8; j++ {
			sum = sum + sl[i][j]
		}
		if sum != 45 {
			return false
		}
		sum = 0
	}

	for i :=

 0; i <= 8; i++ {
		sum := 0
		for j := 0; j <= 8; j++ {
			sum = sum + sl[j][i]
		}
		if sum != 45 {
			return false
		}
		sum = 0
	}

	return true
}

func main() {
	arguments := os.Args
	if len(arguments) != 2 {
		fmt.Printf("使用: loadFile 文件名\n")
		return
	}
	file := arguments[1]
	mySlice, err := importFile(file)
	if err != nil {
		fmt.Println(err)
		return
	}

	if validPuzzle(mySlice) {
		fmt.Println("数独正确!")
	} else {
		fmt.Println("数独错误!")
	}
}

通过此程序,您可以从文件导入一个数独,并验证其是否解得正确。输入数独文件格式为9x9的数独矩阵,每行数字间以空格分隔。

运行程序:

bash 复制代码
$ go run sudoku.go valid_sudoku.txt
数独正确!

结论

通过本文的学习,读者不仅能掌握如何在Go语言中生成随机数,还能学会如何生成加密安全的随机数、矩阵运算以及数独验证等高级技术。Go语言为我们提供了丰富的工具,能轻松应对多种编程挑战。

相关推荐
慢慢雨夜34 分钟前
uniapp 苹果安全域适配
java·前端·uni-app
凄凄迷人37 分钟前
前端基于Rust实现的Wasm进行图片压缩的技术文档
前端·rust·wasm·图片压缩
敲代码不忘补水39 分钟前
二十种编程语言庆祝中秋节
java·javascript·python·golang·html
史努比的大头1 小时前
前端开发深入了解性能优化
前端
码农研究僧1 小时前
Java或者前端 实现中文排序(调API的Demo)
java·前端·localecompare·中文排序·collator
吕永强2 小时前
HTML表单标签
前端·html·表单标签
范特西是只猫2 小时前
echarts map地图动态下钻,自定义标注,自定义tooltip弹窗【完整demo版本】
前端·javascript·echarts
麒麟而非淇淋2 小时前
AJAX 进阶 day4
前端·javascript·ajax
图灵苹果2 小时前
【个人博客hexo版】hexo安装时会出现的一些问题
前端·前端框架·npm·node.js
IT-陈3 小时前
app抓包 chrome://inspect/#devices
前端·chrome