项目一个统计需求的实现

分享 Jim ⋅ 于 2016-12-23 10:13:49 ⋅ 最后回复由 琴歌 2016-12-23 11:12:32 ⋅ 77 阅读

场景及需求

  • 数据来自一个新闻网站
  • 之前没有做搜索,所以没有统计搜索的词
  • 需求:
    • 统计所有新闻中涉及的词的次数
    • 分别统计推送的及未推送的新闻(是否推送只是一个状态,相当于2个数据源) 思路及实现
  • 难点:
    • 首先需要找到单词,也就是分词
    • 然后需要统计这些词在新闻的标题和内容中被提及的次数
  • 思路:
    • 首先是分词,我没有想到好的方法,也不想在网上找分词的库(比较烦),所以采用了最简单粗暴的方法--所有相邻的字,都当成单词,比如一个字符串:分享生活见闻, 分享知识。2个字的单词有:“分享”,“享生”,“生活”,“活见”,“见闻”,“闻,”,“,” ,“ 分”,“分享”,“享知”,“知识”。可以看到,出现了很多莫名其妙的单词,其中可以把空格去掉(虽然我没做),但是不能去掉标点符号(需要处理为断句,麻烦,我也没做)
    • 然后是统计,因为我使用的语言是golang,这方面有优势,采用的数据结构是map(类似字典 key:value),map的几个特性:无序,key唯一,因此可以实现去重功能
  • 实现:
    • 获取数据
    kmgSql.LoadConfigWithDbName("UestcNews")
    news1 := kmgSql.MustQuery(`select Title, Content from ArticleList where year(Time)="2016" and Status = "已发布" and IsPushToUestc=0`)
  • 统计的核心代码
func Statistics(new []map[string]string) map[string]int {
    m := make(map[string]int)
    for _,v := range new {
        a := []string{
            v["Title"],
            HTMLPurifierAll(v["Content"]),
        }
        for _,v1 := range a {
            // 统计2个字
            for i, w := 0, 0; i < len(v1); i += w {
                r, l := utf8.DecodeRuneInString(v1[i:])
                c := i + l
                if c >= len(v1) {
                    break
                }
                x, _ := utf8.DecodeRuneInString(v1[c:])
                w = l
                m[string(r) + string(x)] += 1
            }
            // 统计3个字
            for i, w := 0, 0; i < len(v1); i += w {
                r, l := utf8.DecodeRuneInString(v1[i:])
                c := i + l
                if c >= len(v1) {
                    break
                }
                x, l1 := utf8.DecodeRuneInString(v1[c:])
                d := c + l1
                if d >= len(v1) {
                    break
                }
                x1, _ := utf8.DecodeRuneInString(v1[d:])
                w = l
                m[string(r) + string(x) + string(x1)] += 1
            }
            // 统计4个字,一般词语最多就是4个字了
            for i, w := 0, 0; i < len(v1); i += w {
                r, l := utf8.DecodeRuneInString(v1[i:])
                c := i + l
                if c >= len(v1) {
                    break
                }
                x, l1 := utf8.DecodeRuneInString(v1[c:])
                d := c + l1
                if d >= len(v1) {
                    break
                }
                x1, l2 := utf8.DecodeRuneInString(v1[d:])
                e := d + l2
                if e >= len(v1) {
                    break
                }
                x2, _ := utf8.DecodeRuneInString(v1[e:])
                w = l
                m[string(r) + string(x) + string(x1) + string(x2)] += 1
            }
        }
    }
    return m
}

// 去掉所有html
func HTMLPurifierAll(htmlInput string) string {
    p := bluemonday.NewPolicy()
    html := p.Sanitize(htmlInput)
    return html
}
  • 代码没有关键词变色之类的东西,可能看起来比较费劲,下面附上截图

file
file
file

  • 最后,代码求优化,欢迎提出意见及建议
本帖已被设为精华帖!
本帖由 琴歌 于 3周前 加精
回复数量: 3
  • 叶落染尘 王者挽天下,征战洗九州!
    2016-12-23 10:23:21

    虽然没看懂,但是我是来膜拜的~

  • Jim MOD
    2016-12-23 10:28:26

    主要是给大家一个思路,大家可以用自己现在用的语言写一下,很有进步的

  • 琴歌 MOD 逍遥一世之上,睥睨天地之间。
    2016-12-23 11:12:32

    可以的,思路都大同小异~

暂无评论~~
  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles: ~~
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
Ctrl+Enter