[日常] Go语言圣经-函数递归习题
练习 5.1: 修改findlinks代码中遍历n.FirstChild链表的部分,将循环调用visit,改成递归调用。
练习 5.2: 编写函数,记录在HTML树中出现的同名元素的次数。
练习 5.3: 编写函数输出所有text结点的内容。注意不要访问<script>和<style>元素,因为这些元素对浏览者是不可见的。
练习 5.4: 扩展visit函数,使其能够处理其他类型的结点,如images、scripts和style sheets。
// Findlinks1 prints the links in an HTML document read from standard input.
package main import (
"fmt"
"os" "golang.org/x/net/html"
) func main() {
doc, err := html.Parse(os.Stdin)
if err != nil {
fmt.Fprintf(os.Stderr, "findlinks1: %v\n", err)
os.Exit(1)
}
for _, link := range visit(nil, doc) {
fmt.Println(link)
} var res = make(map[string]int)
res = count(res, doc)
for k, v := range res {
fmt.Printf("%s==>%d \n", k, v)
}
//fmt.Println(res)
for _, text := range visit3(nil, doc) {
fmt.Println(text)
} for _, link := range visit4(nil, doc) {
fmt.Println(link)
} } // visit appends to links each link found in n and returns the result.
func visit(links []string, n *html.Node) []string {
if n.Type == html.ElementNode && n.Data == "a" {
for _, a := range n.Attr {
if a.Key == "href" {
links = append(links, a.Val)
}
}
}
/*
练习 5.1: 修改findlinks代码中遍历n.FirstChild链表的部分,将循环调用visit,改成递归调用。
实在是不知道为啥不对,我选择放弃
if n.FirstChild!=nil{
links=visit(links,n.FirstChild)
}else if n.NextSibling!=nil{
//n=n.NextSibling
links=visit(links,n.NextSibling)
}
*/
for c := n.FirstChild; c != nil; c = c.NextSibling {
links = visit(links, c)
}
return links
} /*
练习 5.2: 编写函数,记录在HTML树中出现的同名元素的次数。
*/
func count(res map[string]int, n *html.Node) map[string]int {
if n.Type == html.ElementNode {
res[n.Data]++
}
for c := n.FirstChild; c != nil; c = c.NextSibling {
res = count(res, c)
}
return res
} /*
练习 5.3: 编写函数输出所有text结点的内容。注意不要访问<script>和<style>元素,因为这些元素对浏览者是不可见的。
*/
func visit3(texts []string, n *html.Node) []string {
if n.Type == html.TextNode {
texts = append(texts, n.Data)
}
for c := n.FirstChild; c != nil; c = c.NextSibling {
if c.Data == "script" || c.Data == "style" {
continue
} texts = visit3(texts, c)
}
return texts
} /*
练习 5.4: 扩展visit函数,使其能够处理其他类型的结点,如images、scripts和style sheets。
*/
func visit4(links []string, n *html.Node) []string {
if n.Type == html.ElementNode && (n.Data == "a" || n.Data == "img" || n.Data == "link" || n.Data == "scripts") {
for _, a := range n.Attr {
if a.Key == "href" {
links = append(links, a.Val)
}
}
}
for c := n.FirstChild; c != nil; c = c.NextSibling {
links = visit4(links, c)
}
return links
}
[日常] Go语言圣经-函数递归习题的更多相关文章
- [日常] Go语言圣经-函数多返回值习题
Go语言圣经-函数多返回值1.在Go中,一个函数可以返回多个值2.许多标准库中的函数返回2个值,一个是期望得到的返回值,另一个是函数出错时的错误信息3.如果一个函数将所有的返回值都显示的变量名,那么该 ...
- [日常] Go语言圣经-错误,函数值习题
Go语言圣经-错误 1.panic异常.panic是来自被调函数的信号,表示发生了某个已知的bug 2.任何进行I/O操作的函数都会面临出现错误的可能 3.错误是软件包API和应用程序用户界面的一个重 ...
- [日常] Go语言圣经--接口约定习题
Go语言圣经-接口1.接口类型是对其它类型行为的抽象和概括2.Go语言中接口类型的独特之处在于它是满足隐式实现的3.Go语言中还存在着另外一种类型:接口类型.接口类型是一种抽象的类型4.一个类型可以自 ...
- [日常] Go语言圣经-竞争条件习题
package main import( "fmt" "sync" ) var balance int func Deposit(amount int) { b ...
- [日常] Go语言圣经-可变参数习题
1.参数数量可变的函数称为为可变参数函数,例子就是fmt.Printf和类似函数2.参数列表的最后一个参数类型之前加上省略符号“...”3.虽然在可变参数函数内部,...int 型参数的行为看起来很像 ...
- [日常] Go语言圣经-Slice切片习题
1.Slice(切片)代表变长的序列,序列中每个元素都有相同的类型,一个slice类型一般写作[]T,其中T代表slice中元素的类型:slice的语法和数组很像,只是没有固定长度而已,slice的底 ...
- [日常] Go语言圣经--接口约定习题2
练习 7.3: 为在gopl.io/ch4/treesort (§4.4)的*tree类型实现一个String方法去展示tree类型的值序列. package main import( "f ...
- [日常] Go语言圣经-匿名函数习题
Go语言圣经-匿名函数1.拥有函数名的函数只能在包级语法块中被声明,通过函数字面量(function literal),我们可绕过这一限制,在任何表达式中表示一个函数值2.通过这种方式定义的函数可以访 ...
- [日常] Go语言圣经--复数,布尔值,字符串习题
go语言圣经-复数 1.我们把形如a+bi(a,b均为实数)的数称为复数,其中a称为实部,b称为虚部,i称为虚数单位.两种精度的复数类型:complex64和complex128,分别对应float3 ...
随机推荐
- Flash插件flashplugin-nonfree的手动更新
Debian,nonfree库里有flashplugin-nonfree,这个就是网页浏览器的Flash插件了.不过它好像不会自动更新,每次更新网页浏览器后都会提示flashplugin版本过低.但f ...
- C# 动态创建SQL数据库(一)
最近在做项目中要求能够要求动态添加数据库并建表.具体思路如下 1 提供数据名,根据数据库创建数据库 2 自定数据库与数据表,提供数据表自定与数据类型创建表 创建sqlhelper类,用于数据库操作 u ...
- OSLab文件描述符
日期:2019/3/24 内容:Linux文件描述符. 一.基本概念 文件描述符(File Descriptor) 一个非负整数.应用程序利用文件描述符来访问文件.打开现存文件或新建文件时,内 ...
- 12_python_生成器
一.生成器 python中有三种方式获取生成器 (1)通过生成器函数 (2)通过各种推导式来实现生成器 (3)通过数据的转换也可以获取生成器 1.只要函数中存在了yield,那么这个函数就是一个生 ...
- Weblogic 错误 <BEA-000403> <BEA-000438>解决办法
控制台提示如下错误: <Error> <Socket> <BEA-000438> <Unable to load performance pack. Us ...
- Java - 初识Java
Java是一种跨平台的面向对象的程序设计语言. 区分大小写: 标点符号为英文: 强类型语言,在Java中存储的数据,必须在编译时确定其类型: Java版本 Java按应用范围分为3个版本,即Java ...
- Others - On Duty
On Duty This is xxx and will be duty engineer in the next week. Thanks. Here is a kindly reminder. T ...
- [Leetcode]44.跳跃游戏Ⅰ&&45.跳跃游戏Ⅱ
跳跃游戏链接 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] 输出 ...
- Strom的trident小例子
上代码: public class TridentFunc { /** * 类似于普通的bolt */ public static class MyFunction extends BaseFunct ...
- Installation failed with message...It is possible that this issue is resolved by uninstalling an existing version of the apk if it is present, and then re-installing.
错误弹窗如图: Installation failed with message Failed to finalize session: INSTALL_FAILED_TEST_ONLY:instal ...