Golang语法的25个练习题:16至20题
题目16:大衍数列
中国古代文献中,曾记载过“大衍数列”,主要用于解释中国传统文化中的太极衍生原理
它的前几项是:0、2、4、8、12、18、24、32、40、50…
其规律是:偶数项,是序号平方再除2,奇数项,是序号平方减1再除2。
打印大衍数列的前100项
package main
import (
"fmt"
"math"
)
func main() {
for i := 1; i <= 100; i++ {
var a int
if i%2 == 0 { // 偶数
a = int(math.Pow(float64(i), 2)) / 2
} else { // 奇数
a = (int(math.Pow(float64(i), 2)) - 1) / 2
}
fmt.Println("//", a)
}
// 0
// 2
// 4
// 8
// 12
// 18
// 24
// 32
// 40
// 50
}
题目17:单词分析
- 小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词
- 现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这个字母出现的次数
- 其实就是让你输入一段字符串后,得到当前字符串出现最多的字母和它的次数
- 输入:HelloWorld
- 输出:
- l
- 3
- 我们可以对当前的字符串进行循环迭代,然后把字符串当前每个字符当作key值,把它存到字典里面,如果当前key在字典里面,我们就让它加一,如果不在那我们就让它的次数初始化为1,最终我们再从字典找到次数最多的key值和value值
package main
import "fmt"
func main() {
analyseWords("helloworld")
// l 3
}
func analyseWords(word string) {
wordDict := map[rune]int{}
var (
count int
ch rune
)
for _, c := range word {
wordDict[c]++
if wordDict[c] > count {
count, ch = wordDict[c], c
}
}
fmt.Println(string(ch), count)
}
题目18:利用栈打印菱形
输入边长n,打印对应边长的菱形
分析:
- 打印几行
- 每一行打印几个空格,几个星星
- 前几行打印之前加入到栈,利用栈的后进先出原则打印后几行的内容
package main
import (
"fmt"
"strings"
)
func main() {
diamond(5)
// *
// ***
// *****
// *******
// *********
// *******
// *****
// ***
// *
}
func diamond(n int) {
var stack []string
for i := 1; i < 2*n; i++ {
var pStr string
if i <= n {
pStr = strings.Repeat(" ", n-i) + strings.Repeat("*", 2*i-1)
if i != n {
stack = append(stack, pStr)
}
} else {
pStr = stack[len(stack)-1]
stack = stack[:len(stack)-1]
}
fmt.Println("//", pStr)
}
}
题目19:深入理解递归函数
什么是递归函数?
递归函数就是一个函数在它的函数体内调用它自身。执行递归函数将反复调用其自身,每调用一次就进入新的一层。
递归函数必须有结束条件。
设计递归函数三要素:
- 明确你这个函数想要干什么
- 寻找递归结束条件
- 找出函数的等价关系式
package main
import "fmt"
func main() {
p(5)
//递归前-> 5
//递归前-> 4
//递归前-> 3
//递归前-> 2
//递归前-> 1
//递归后-> 1
//递归后-> 2
//递归后-> 3
//递归后-> 4
//递归后-> 5
}
func p(n int) {
if n == 0 {
return
}
fmt.Println("//递归前->", n)
defer fmt.Println("//递归后->", n)
p(n - 1)
}
题目20:斐波那契递归函数
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:
1、1、2、3、5、8、13、21、34、…
这个数列,前两项都是数字1,从第三项开始,每一项数字是前两项数字之和
关系表达式【f(n) = f(n-1)+f(n-2)】
package main
import "fmt"
func main() {
fmt.Println(fib(10)) //89
fmt.Println(fib(2)) //2
fmt.Println(fib(5)) //8
fmt.Println(fib2(10)) //89
fmt.Println(fib2(2)) //2
fmt.Println(fib2(5)) //8
}
func fib(n int) int {
if n <= 2 {
return n
}
return fib(n-1) + fib(n-2)
}
var mp = map[int]int{}
func fib2(n int) int {
if n <= 2 {
return n
}
// 记忆化递归
if k, ok := mp[n]; ok {
return k
}
return fib(n-1) + fib(n-2)
}
递归与栈的关系
递归函数原理:每一次调用都会把当前调用压入到栈里,最后按照后进先出的原则,不停返回返回
由递归程序的执行过程,我们得知递归程序的调用是一层层向下的,而返回过程则恰好相反,一层层向上。
换个说法:最先一次的函数调用在最后返回,而最后一次的函数调用则是最先返回。这就跟栈的“后进先出”次序是一样的。因此,在实现递归调用的时候,通常就会使用栈来保存每一次调用的现场数据:
- 当一个函数被调用的时候,系统会把调用时的现场数据压入到系统调用栈,压入栈的现场数据称为栈帧。
- 当函数返回时,要从调用栈的栈顶取得返回地址,恢复现场,弹出栈帧,按地址返回。
python原文:https://www.52pojie.cn/thread-1689186-1-1.html