数组和切片实战

1).检查某个值是否在数组中:

如果要检查某个值是否在在数组或切片中.则需要根据相应的类型进行逐个对比.

示例:

go 复制代码
package main

import (
    "encoding/csv"
    "fmt"
    "math/rand"
    "os"
    "regexp"
    "strings"
    "time"
    "unicode/utf8"
)

func main() {
    nameList := []string{"Barry", "Shirdon", "Jack"}
    str1 := "Barry"
    str2 := "Go"
    result := Exist(str1, nameList)
    fmt.Println(result)
    result2 := Exist(str2, nameList)
    fmt.Println(result2)
}

func Exist(target string, array []string) bool {
    for _, v := range array {
       if target == v {
          return true
       }
    }
    return false
}

执行结果:

2).查找一个元素在数组中的位置:

如果要查找一个元素在数组中的位置.首先通过reflect包的ValueOf()函数获取数组的值.然后用for循环遍历数组对值进行比较.如果相等.返回元素的索引值.

示例:

go 复制代码
package main

import (
    "encoding/csv"
    "fmt"
    "math/rand"
    "os"
    "reflect"
    "regexp"
    "strings"
    "time"
    "unicode/utf8"
)

func main() {
    a := make([]int, 6)
    for i := 0; i < 6; i++ {
       a[i] = i + 2
    }
    index := arrayPosition(a, 6)
    fmt.Println(index)
}

func arrayPosition(arr interface{}, d interface{}) int {
    array := reflect.ValueOf(arr)
    for i := 0; i < array.Len(); i++ {
       v := array.Index(i)
       if v.Interface() == d {
          return i
       }
    }
    return -1
}

执行结果:

3).查找数组中最大值或最小值:

在Go语言中.如果要查找数组中最大值或最小值元素.可以通过for循环逐个比较元素的大小.发现更大的数则进行交换.

示例:

less 复制代码
package main

import (
    "encoding/csv"
    "fmt"
    "math/rand"
    "os"
    "reflect"
    "regexp"
    "strings"
    "time"
    "unicode/utf8"
)

func main() {
    var array = [...]int{1, -2, 88, 66, 16, 68}
    maxValue := array[0]
    maxValueIndex := 0
    for i := 0; i < len(array); i++ {
       //比较元素大小.如果发现更大的数.则进行交换.
       if maxValue < array[i] {
          maxValue = array[i]
          maxValueIndex = i
       }
    }
    fmt.Println("maxValue=% v maxValue=%v \n", maxValue, maxValueIndex)
}

执行结果:

4).随机打乱数组:

把一个数组随机打乱的实质就是"洗牌问题"."洗牌问题"不仅追求速度.还要求洗的足够开.

Fisher-Yates随机置乱算法也称高纳德置乱算法.核心思想是从1n之间随机出一个数和最后一个数(n)交换.然后从1n-1之间随机出一个数和倒数第二个数(n-1)交换.这个算法生成的随机排列是等概率的.所以每个排列都有可能.

示例:

go 复制代码
package main

import (
    "encoding/csv"
    "errors"
    "fmt"
    "math/rand"
    "os"
    "reflect"
    "regexp"
    "strings"
    "time"
    "unicode/utf8"
)

func init() {
    rand.Seed(time.Now().Unix())
}

func main() {
    str := []string{
       "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
    }
    a, _ := RandomInt(str, 5)
    fmt.Println(a)

}

func RandomInt(str []string, length int) (string, error) {
    if len(str) <= 0 {
       return "", errors.New("字符串长度不能小于0")
    }
    if length <= 0 || len(str) <= length {
       return "", errors.New("参数长度非法")
    }
    for i := len(str) - 1; i > 0; i-- {
       num := rand.Intn(i + 1)
       str[i], str[num] = str[num], str[i]
    }
    str1 := ""
    for i := 0; i < length; i++ {
       str1 += str[i]
    }
    return str1, nil
}

执行结果:

5).删除数组中重复的元素:

给定一个数组.需要删除重复出现的元素.使得每个元素只出现一次.并返回移除后数组的新长度.不需要额外的数组空间.必须通过直接修改输入数组的方式.并在使用空间复杂度为O(1)的条件下完成.

示例:

sql 复制代码
package main

import (
    "encoding/csv"
    "errors"
    "fmt"
    "math/rand"
    "os"
    "reflect"
    "regexp"
    "strings"
    "time"
    "unicode/utf8"
)



func main() {
    array := []int{1, 6, 6, 8}
    res := removeDuplicates(array)
    fmt.Println(res)
}

func removeDuplicates(array []int) []int {
    //如果空切片.返回nil.
    if len(array) == 0 {
       return nil
    }
    //用两个标记来比较相邻位置的值.
    //如果一样.则继续.
    //如果不一样.则把right指向的值赋值给left下一位.
    left, right := 0, 1
    for ; right < len(array); right++ {
       if array[left] == array[right] {
          continue
       }
       left++
       array[left] = array[right]
    }
    return array[:left+1]
}

执行结果:

6).一维数组的排序:

在Go语言中.只要实现了sort.Interface接口.即可通过sort包内的函数完成排序 查找等操作.并且sort包已经把[]int []float64 []string三种类型都实现了该接口.

sort.Sort()函数是递增排序.如果要实现递减排序.则要用sort.Reverse()函数.

7).二维数组排序:

对于二维数组排序.可以通过实现sort.Interface接口算法来实现.

给定一个二维数组.将这个二维数组按第i列(i从1开始)排序.如果第i列相同.即对相同的行按第i+1列的元素排序.如果第i+1列的元素也相同.则继续比较第i+2列.以此类推.直到最后一列.如果第i列到最后一列都相同.则按原序排列.

示例:

go 复制代码
package main

import (
    "encoding/csv"
    "errors"
    "fmt"
    "math/rand"
    "os"
    "reflect"
    "regexp"
    "sort"
    "strings"
    "time"
    "unicode/utf8"
)

func main() {
    //二维数组.
    nums := [][]int{{1, 9, 5}, {2, 3, 6}, {3, 6, 9}, {1, 8, 3}}
    firstIndex := 1
    result := ArraySort(nums, firstIndex)
    fmt.Println(result)
}

func ArraySort(numArray [][]int, firstIndex int) [][]int {
    //检查.
    if len(numArray) <= 1 {
       return numArray
    }
    if firstIndex < 0 || firstIndex > len(numArray[0])-1 {
       fmt.Println("Warning:Param firstIndex should between 0 and len(numArray)-1.thr original array is returned.")
       return numArray
    }
    //排序.
    in := &IntArray{numArray, firstIndex}
    sort.Sort(in)
    return in.mArr
}

type IntArray struct {
    mArr       [][]int
    firstIndex int
}

// 实现sort.Interface接口.
func (in *IntArray) Len() int {
    return len(in.mArr)
}

func (in *IntArray) Swap(i, j int) {
    in.mArr[i], in.mArr[j] = in.mArr[j], in.mArr[i]
}

func (in *IntArray) Less(i, j int) bool {
    arr1 := in.mArr[i]
    arr2 := in.mArr[j]
    // 取两行较短的长度,防止越界
    minLen := len(arr1)
    if len(arr2) < minLen {
       minLen = len(arr2)
    }
    for idx := in.firstIndex; idx < minLen; idx++ {
       if arr1[idx] != arr2[idx] {
          return arr1[idx] < arr2[idx]
       }
    }
    return i < j
}

执行结果:

8).三维数组生成:

创建一个三维数组生成器.需要通过make()函数和for-range循环语句配合实现.

示例:

go 复制代码
package main

import (
    "encoding/csv"
    "errors"
    "fmt"
    "math/rand"
    "os"
    "reflect"
    "regexp"
    "sort"
    "strings"
    "time"
    "unicode/utf8"
)

func main() {
    x := make3D(2, 2, 3)
    x[1][0][2] = 9
    fmt.Println(x)
}
func make3D(m, n, p int) [][][]float64 {
    buf := make([]float64, m*n*p)
    x := make([][][]float64, m)
    for i := range x {
       x[i] = make([][]float64, n)
       for j := range x[i] {
          x[i][j] = buf[:p:p]
          buf = buf[p:]
       }
    }
    return x
}

执行结果:

相关推荐
卷无止境2 小时前
过度设计如何避免(java举例)
后端
派星2 小时前
PageHelper 与 MyBatis 的分页查询协作原理
后端
卷无止境2 小时前
AI编程时代,什么需求使用rust开发最合适?
后端
lagrahhn3 小时前
ES索引的基础和进阶内容
后端·elasticsearch·搜索引擎
SamDeepThinking3 小时前
秒杀系统怎么区分真实用户和黄牛脚本?
java·后端·架构
stark张宇3 小时前
深入Go运行时:数值溢出、浮点精度与栈堆分配决策
后端·go
fliter3 小时前
Rust 里最让人头疼的两个类型:Pin 和 Unpin,究竟解决了什么问题?
后端
覆东流3 小时前
第7天:Python小项目
开发语言·后端·python
码化豚3 小时前
揭秘外卖平台城市区域地理围栏/电子围栏设计
后端