分享
  1. 首页
  2. 文章

go标准库实现---ASCII 字符包含判断

爱简单 · · 2468 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

@TOC

ASCII 字符包含判断

最近换工作,暂时离开了世界上最好的语言,成为了一名 golanger (这好象是一个 web 框架的名字),这一次打算养成良好的习惯,那就从写博客开始吧。

文章背景

正在琢磨自己用 go 实现一个脚本语言,写词法分析的时候,需要匹配字符串的功能,既然编译器都自己写了,这也自己写一个吧,去研究了下 go 的实现,发现设计的很巧妙,所以分享一下,美中不足的是只适用于 ascii 码

源码展示

type asciiSet [8]uint32
const RuneSelf = 0x80
// 判断是否包含
func (as *asciiSet)contains(c rune) bool {
 return (as[c>>5] & (1 << uint(c&31))) != 0
}
// 生成 ascii 哈希表
func makeASCIISet(chars string) (as asciiSet, ok bool) {
 for i := 0; i < len(chars); i++ {
 c := chars[i]
 if c >= RuneSelf {
 return as, false
 }
 as[c>>5] |= 1 << uint(c&31)
 }
 return as, true
}

代码解析

type asciiSet [8]uint32

asciiSet 这是一个分了 8 个桶的哈希表(位图),用于存储匹配串包含的字符集合
匹配串输入后,将会被按位存储在 asciiSet

下面这行代码,会对所有包含 非 asci i字符的串直接返回 false

if c >= utf8.RuneSelf {
 return as, false
}

下面这行代码可以看作一个哈希算法。

1 << uint(c&31)

会把单个字符对应到一个 32位 的位图上面,

  • &31 是由于分桶的设计,将高 3 位作为了桶标记
  • 1 << 将 1 左移 0-31 位,用于存储已有的字符
(as[c>>5] & (1 << uint(c&31))) != 0

从字符对应的桶中取出位图,然后查看是否存在

思考

asciiSet 是其中的关键,但是也由于其大小限制加上移位操作,导致只适用于基础ascii,
当然,进行一定修改可以适用于更大的字符集,不过内存使用量会比较大。


有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:爱简单

查看原文:go标准库实现---ASCII 字符包含判断

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
2468 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏