Golang 百题(实战快速掌握语法)_2

返回集合中满足指定条件的最后一个元素

本实验将实现判断给定集合中的元素是否符合,并返回符合的最后一个元素。

知识点
  • for
  • fmt.Error
适合人群

本课程属于基础课程。需要用户掌握 Go 语言编程基础知识、计算机基础知识和 Linux 环境的基本用法。

许可证

内容编译来自 psampaz30s-seconds-of-golang 的开源项目,它们分别使用 CC BY-SA 4.0 LicenseCC0-1.0 License,为了能够适合实验楼在线环境,我们修改了部分解题和单元测试代码。

代码实例

我们可以使用 for 循环倒序遍历来进行查看,因为 Go 中参数可以为函数,所有我们使用判断函数来作为判断的参数传入主函数中,下面是一个例子。

package main

import "fmt"

func FindLastInt(arr []int, f func(int) bool) (int, error) {
    for i := len(arr) - 1; i >= 0; i-- {
        if f(arr[i]) {
            return arr[i], nil
        }
    }
    return 0, fmt.Errorf("No matches found")
}
func FindLastFloat64(arr []float64, f func(float64) bool) (float64, error) {
    for i := len(arr) - 1; i >= 0; i-- {
        if f(arr[i]) {
            return arr[i], nil
        }
    }
    return 0.0, fmt.Errorf("No matches found")
}
func FindLastBool(arr []bool, f func(bool) bool) (bool, error) {
    for i := len(arr) - 1; i >= 0; i-- {
        if f(arr[i]) {
            return arr[i], nil
        }
    }
    return false, fmt.Errorf("No matches found")
}
func FindLastString(arr []string, f func(string) bool) (string, error) {
    for i := len(arr) - 1; i >= 0; i-- {
        if f(arr[i]) {
            return arr[i], nil
        }
    }
    return "", fmt.Errorf("No matches found")
}
func main() {
    r1, ch1 := FindLastInt([]int{1, 1, 2}, func(x int) bool { return x%2 == 0 }) // 2 nil
    fmt.Println(r1, ch1)
}

该程序的功能:

  • 使用 for 循环逆序遍历给定的集合
  • 使用函数 f 来判断是否是符合条件的元素
  • 如果符合条件,则输出元素和 nil,否则输出 0 和错误信息
  • 使用fmt.Error()来生成错误

将代码保存为/home/project/findLast.go文件。

运行程序

打开 WebIDE 的 Terminal 终端,输入以下命令查看输出:

go run findLast.go

总结

本实验我们学习了如何返回集合中满足指定条件的最后一个元素,下个实验我们将讲解如何对给定的集合进行分组。

对给定的集合进行分组

本实验将实现对输入的多个集合按照索引进行分组然后返回这个新的集合。

知识点
  • for
  • reflect
适合人群

本课程属于基础课程。需要用户掌握 Go 语言编程基础知识、计算机基础知识和 Linux 环境的基本用法。

许可证

内容编译来自 psampaz30s-seconds-of-golang 的开源项目,它们分别使用 CC BY-SA 4.0 LicenseCC0-1.0 License,为了能够适合实验楼在线环境,我们修改了部分解题和单元测试代码。

代码实例

本实验我们将使用...来对给定的多个集合按照索引进行整合,下面是一个例子。

package main

import (
    "fmt"
    "reflect"
)

func Zip(params ...interface{}) [][]interface{} {
    l := 0
    for i := range params {
        arr := reflect.ValueOf(params[i])
        if l < arr.Len() {
            l = arr.Len()
        }
    }
    r := make([][]interface{}, l)

    for i := 0; i < l; i++ {
        r[i] = make([]interface{}, 0)
        for j := range params {
            v := reflect.ValueOf(params[j])
            if v.Len() > i {
                r[i] = append(r[i], v.Index(i).Interface())
            }
        }
    }
    return r
}
func main() {
    s := []string{"a", "b"}
    i := []int{1, 2}
    b := []bool{true, false}
    r1 := Zip(s, i, b) // [[a 1 true] [b 2 false]]
    fmt.Println(r1)
}

该程序的功能:

  • 使用 make 创建一个二维interface{}数组,并将长度设置为最长的集合
  • 使用 for 循环来遍历给定的多个数组,然后把数组中相同索引的值加到设置的二维数组中。

将代码保存为/home/project/zip.go文件。

运行程序

打开 WebIDE 的 Terminal 终端,输入以下命令查看输出:

go run zip.go

图片描述

总结

本实验我们学习了对多个给定的集合进行索引的分组,下个实验我们将讲解如何判断给定的字符串是否为回文。

判断是否为回文

回文是指正读和反读一样的字符,本实验将判断输入的字符串是否为回文。(本题样例不区分大小写只按正读和反读区分是否回文)

知识点
  • range
适合人群

本课程属于基础课程。需要用户掌握 Go 语言编程基础知识、计算机基础知识和 Linux 环境的基本用法。

许可证

内容编译来自 psampaz30s-seconds-of-golang 的开源项目,它们分别使用 CC BY-SA 4.0 LicenseCC0-1.0 License,为了能够适合实验楼在线环境,我们修改了部分解题和单元测试代码。

代码实例

我们分别使用两个变量分别位于字符串的首尾,如果这两个变量相同则它们分别移动一次向中间靠拢,下面是具体的实现。

package main

import (
    "fmt"
    "strings"
)

func IsPalindrome(s string) bool {
    v := strings.ToLower(strings.Join(strings.Fields(s), ""))
    for i := range v {
        if v[len(v)-i-1] != v[i] {
            return false
        }
    }
    return true
}
func main() {
    r := IsPalindrome("taco cat")
    fmt.Println(r)
}

该程序的功能:

  • 使用strings.ToLower使得输入的字符串全部转为小写。
  • for 循环判断字符串的两侧。

将代码保存为/home/project/isPalindrome.go文件。

运行程序

打开 WebIDE 的 Terminal 终端,输入以下命令查看输出:

go run isPalindrome.go

图片描述

总结

本实验我们学习了如何通过首尾参数来判断给定的字符串是否为回文,下个实验我们将学习如何连接同类型的切片。

连接切片

Go 语言中连接同种类型的不同切片,可以使用 append 函数,本实验将实现对输入的切片进行连接。

知识点
  • append
适合人群

本课程属于基础课程。需要用户掌握 Go 语言编程基础知识、计算机基础知识和 Linux 环境的基本用法。

许可证

内容编译来自 psampaz30s-seconds-of-golang 的开源项目,它们分别使用 CC BY-SA 4.0 LicenseCC0-1.0 License,为了能够适合实验楼在线环境,我们修改了部分解题和单元测试代码。

代码实例

我们使用 append 和...来进行切片的连接,其中...的作用表示传入切片的多个值,通常用在接受多个不确定数量的参数和表示函数有多个不定参数的情况,下面是一个例子。

package main

import "fmt"

func ConcatInt(a, b []int) []int {
    return append(a, b...)
}
func ConcatFloat64(a, b []float64) []float64 {
    return append(a, b...)
}
func ConcatBool(a, b []bool) []bool {
    return append(a, b...)
}
func ConcatStrings(a, b []string) []string {
    return append(a, b...)
}
func main() {
    d1, d2 := []string{"a", "b", "c"}, []string{"d", "e"}
    r := ConcatStrings(d1, d2) // [a b c d e]
    fmt.Println("date1 ", d1, "\ndate2 ", d2, "\nresult: ", r)
}

该程序的功能:

  • 使用 append 和可变参数...来扩展 slice

将代码保存为/home/project/concat.go文件。

运行程序

打开 WebIDE 的 Terminal 终端,输入以下命令查看输出:

go run concat.go

图片描述

总结

本实验我们学习了如何通过不定参数变量和 append 连接切片的方法,下个实验我们将讲解求多个数字的最大公约数。

求多个数字的最大公约数

本实验将求多个数字的最小公约数。

知识点
  • 递归
  • for
适合人群

本课程属于基础课程。需要用户掌握 Go 语言编程基础知识、计算机基础知识和 Linux 环境的基本用法。

许可证

内容编译来自 psampaz30s-seconds-of-golang 的开源项目,它们分别使用 CC BY-SA 4.0 LicenseCC0-1.0 License,为了能够适合实验楼在线环境,我们修改了部分解题和单元测试代码。

代码实例

公约数是指能同时整除几个整数的数,本实验我们将两两遍历,把求得的公约数作为下一次循环的一项进行计算,下面是一个例子。

package main

import "fmt"

func gcd(x, y int) int {
    if y == 0 {
        return x
    }
    return gcd(y, x%y)
}

func GCD(nums ...int) int {
    r := nums[0]
    for _, num := range nums[1:] {
        r = gcd(r, num)
    }
    return r
}
func main() {
    r1 := GCD(8, 36)               // 4
    r2 := GCD([]int{11, 8, 32}...) // 1  这里的...为了将切片展开成可变参数
    fmt.Println(r1, r2)
}

该程序的功能:

  • 使用 gcd 函数创建一个递归。
  • 递归的返回条件是当 y 为 0 时,返回 x。
  • 使用 range 和 gcd 函数来为给定的每一个数字进行计算。

将代码保存为/home/project/gcd.go文件。

运行程序

打开 WebIDE 的 Terminal 终端,输入以下命令查看输出:

go run gcd.go

图片描述

总结

本实验我们学习了如何求多个数字的最大公约数,下个实验我们将学习如何求多个数字的最小公倍数。

求多个数字的最小公倍数

两个或多个整数公有的倍数叫做它们的公倍数,最小公倍数是指其中除 0 以外最小的一个公倍数,本实验将实现通过递归求解多个数字的最小公倍数。

知识点
  • for
  • 递归
适合人群

本课程属于基础课程。需要用户掌握 Go 语言编程基础知识、计算机基础知识和 Linux 环境的基本用法。

许可证

内容编译来自 psampaz30s-seconds-of-golang 的开源项目,它们分别使用 CC BY-SA 4.0 LicenseCC0-1.0 License,为了能够适合实验楼在线环境,我们修改了部分解题和单元测试代码。

代码实例

本实验我们将使用递归来获得多个数字的最小公倍数,下面是一个例子。

package main

import (
    "fmt"
)

func gcd(x, y int) int {
    if y == 0 {
        return x
    }
    return gcd(y, x%y)
}

func LCM(nums ...int) int {
    x := nums[0]
    for _, y := range nums[1:] {
        x = (x * y) / gcd(x, y)
    }
    return x
}
func main() {
    r1 := LCM(12, 7)                // 84
    r2 := LCM([]int{1, 3, 4, 5}...) // 60
    fmt.Println(r1, r2)
}

该程序的功能:

  • 使用 gcd 函数创建一个递归。
  • 递归的返回条件是当 y 为 0 时,返回 x。
  • 使用 range 和 gcd 函数来为给定的每一个数字进行计算。

将代码保存为/home/project/lcm.go文件。

运行程序

打开 WebIDE 的 Terminal 终端,输入以下命令查看输出:

go run lcm.go

图片描述

总结

本实验我们讲解了如何求多个数组的最小公倍数,下个实验我们将学习返回指定范围内的切片。

返回指定范围内的切片

本实验将给定一个起始终止,递增的范围。返回指定范围的切片。

知识点
  • range
  • fmt
适合人群

本课程属于基础课程。需要用户掌握 Go 语言编程基础知识、计算机基础知识和 Linux 环境的基本用法。

许可证

内容编译来自 psampaz30s-seconds-of-golang 的开源项目,它们分别使用 CC BY-SA 4.0 LicenseCC0-1.0 License,为了能够适合实验楼在线环境,我们修改了部分解题和单元测试代码。

代码实例

本实验我们输入起始,终止和递增的范围,来生成指定范围内的切片,下面是一个例子。

package main

import (
    "fmt"
)

func IntRange(f, t, s int) []int {
    arr := make([]int, (t-f+1)/s)
    for i := range arr {
        arr[i] = i*s + f
    }
    return arr
}
func main() {
    r1 := IntRange(0, 9, 2)
    fmt.Println(r1)
}

该程序的功能:

  • 使用 make 创建一个适合大小的切片
  • 使用 range 来迭代切片并且填充。

将代码保存为/home/project/intRange.go文件。

运行程序

打开 WebIDE 的 Terminal 终端,输入以下命令查看输出:

go run intRange.go

图片描述

总结

本实验我们学习了如何返回指定范围内的切片,下一个实验我们将讲解如何获得指定范围内的随机切片。

返回指定范围内的随机切片

本实验我们将分别输入起始范围,终止范围来实现生成指定范围内的随机数组,这里随机我们使用的是 math/rand。

知识点
  • math/rand
适合人群

本课程属于基础课程。需要用户掌握 Go 语言编程基础知识、计算机基础知识和 Linux 环境的基本用法。

许可证

内容编译来自 psampaz30s-seconds-of-golang 的开源项目,它们分别使用 CC BY-SA 4.0 LicenseCC0-1.0 License,为了能够适合实验楼在线环境,我们修改了部分解题和单元测试代码。

代码实例

本实验我们将使用math/rand包来生成指定范围的随机切片,下面是一个例子。

package main

import (
    "fmt"
    "math/rand"
)

func RandIntSliceInRange(min, max, n int) []int {
    arr := make([]int, n)

    for i := range arr {
        arr[i] = rand.Intn(max-min) + min //随机范围切片
    }
    return arr
}
func main() {
    r1 := RandIntSliceInRange(12, 35, 10)
    fmt.Println(r1)
}

该程序的功能:

  • 使用make创建一个合适大小的切片。
  • 使用 range 来遍历切片,并且用 rand.Intn()来生成指定范围内的随机数添加到切片中。

将代码保存为/home/project/randIntSliceInRange.go文件。

运行程序

打开 WebIDE 的 Terminal 终端,输入以下命令查看输出:

go run randIntSliceInRange.go

图片描述

总结

本实验我们使用 rand 生成了一个指定范围内的切片,下一个实验我们将讲解如何求集合中的中位数。

求集合中的中位数

中位数是按顺序排列的一组数据中居于中间位置的数,本实验我们将通过使用 sort 函数和 for 循环获得集合的中位数。

知识点
  • sort
  • for
适合人群

本课程属于基础课程。需要用户掌握 Go 语言编程基础知识、计算机基础知识和 Linux 环境的基本用法。

许可证

内容编译来自 psampaz30s-seconds-of-golang 的开源项目,它们分别使用 CC BY-SA 4.0 LicenseCC0-1.0 License,为了能够适合实验楼在线环境,我们修改了部分解题和单元测试代码。

代码实例

Go 语言 Sort 包下的 Float64s 函数可以对输入的集合进行升序排序列,用法如下:

func Float64s(a []float64)

下面我们将使用 sort 来求给定集合的中位数,下面是一个例子。

package main

import (
    "fmt"
    "math"
    "sort"
)

func Median(nums ...float64) float64 {
    m, n := int(math.Floor(float64(len(nums))/2.0)),
        nums[:]   //Floor将结果向下取整
    sort.Float64s(n)

    if len(nums)%2 == 0 {
        return (n[m-1] + n[m]) / 2.0
    }
    return n[m]
}
func main() {
    r1 := Median(5.0, 6.0, 50.0, 1.0, -5.0)
    r2 := Median(1.0, 2.0, 4.0, 5.0)
    fmt.Println("中位数:", r1, "中位数:", r2)
}

该程序的功能:

  • 找到中位数 m。
  • 使用 sort.Float64s 来对 nums 进行排序。
  • 分情况进行判断,如果是偶数则返回俩个中位数的平均数。

将代码保存为 /home/project/median.go 文件。

运行程序

打开 WebIDE 的 Terminal 终端,输入以下命令查看输出:

go run median.go

图片描述

总结

本实验我们学习了使用 sort 包和 for 循环获得集合中位数的方法,了解他们的实验原理我们才能更好的使用他们。

转换 Lisp 式字符串

挑战介绍

把输入的字符串转换为烤肉串式类型。

挑战内容

本次挑战中,你需要把输入的字符串转换为烤肉串式类型。

输出参考格式为:

# 输入
some text
# 输出
some-text

挑战要求

  • 请自行在环境主目录/home/project下新建 convert_lisp.go 文件,并复制示例代码到文件中完成补充。补充完整后点击「提交检测」,系统将会给出判定结果。

图片描述

示例代码

package main

import (
    "bufio"
    "fmt"
    "log"
    "os"
    "strings"
)

func main() {
    fmt.Println("Input strings: ")
    inp := bufio.NewReader(os.Stdin)

    // res 为输出的Lisp字符串
    // s为输入的字符串
    var res string
    s, err := inp.ReadString('\n')
    if err != nil {
        log.Fatal("wrong input")
    }
    // 待补充部分


    fmt.Println(res)
}

小贴士

  • 可以使用 strings 包下的功能函数来进行处理。
  • 为了保证能被系统准确检测,挑战中的每一句话都非常重要,请仔细阅读。跳跃式浏览易导致挑战无法按要求通过。
参考代码

以下内容仅供参考,为了能有更好的学习效果,请尽量按自己的想法来完成挑战。

参考答案

package main

import (
    "bufio"
    "fmt"
    "log"
    "os"
    "strings"
)

func main() {
    fmt.Println("Input strings: ")
    inp := bufio.NewReader(os.Stdin)

    // res 为输出的Lisp字符串
    // s为输入的字符串
    var res string
    s, err := inp.ReadString('\n')
    if err != nil {
        log.Fatal("wrong input")
    }
    res = strings.Join(strings.Fields(s), "-")
    fmt.Println(res)
}

版权说明

内容编译来自 psampaz30s-seconds-of-golang 的开源项目,它们分别使用 CC BY-SA 4.0 LicenseCC0-1.0 License,为了能够适合实验楼在线环境,我们修改了部分解题和单元测试代码。

  • 28
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值