• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

[日常]Go语言圣经-函数递归习题

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

练习 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
}

  


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
go6---slice切片发布时间:2022-07-10
下一篇:
Go Channel的实现发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap