大家好,我是站长 polarisxu。
今天要聊的内容应该可以当做一道面试题,你可以先想想该怎么实现。
统计字数是一个很常见的需求,很多人印象最深的应该是微博早些时候限制 140 字,而且边输入会边统计剩余字数。现在很多社区文章也会有字数统计的功能,而且可以依据字数来预估阅读时间。比如 Go语言中文网就有这样的功能。
01 需求分析
下手之前先分析下这个需求。从我个人经验看,在实际面试中,针对一个面试题,你的分析过程,循序渐进的解决方案,可以很好的展示你的思考过程。正所谓分析问题、解决问题。这会给你加分的。
我们采用类似词法分析的思路分析这个需求。
一篇文章通常包含如下元素,我们也称之为 token:
- 普通文字
- 标点符号
- 图片
- 链接(包含各种协议的链接)
- 代码
其中普通文字通常会分为欧美和中日韩(CJK),因为 CJK 属于表意文字,和欧美字母的文字差异很大。同时这里还涉及到编码的问题。本文假设使用 UTF-8 编码。
对于标点符号,中文标点和英文标点也会很不一样。
此外还有全角和半角的问题。
根据以上分析,对于该需求作如下假定:
- 空格(包括换行)不算字数;
- HTML 标签需要剔除;
- 编码方式:假定为 UTF-8 编码;
- 标点符号算不算做字数。如果算,像括号这样的按 2 个字算;
- 链接怎么算?一个链接约定为 1 个字可能更合适,大概阅读时只是把它当链接,而不太会关心链接由什么字母组成;
- 图片不算做字数,但如果计算阅读时间,可能需要适当考虑图片的影响;
- 对于技术文章,代码是最麻烦的。统计代码字数感觉是没多大意义的。统计代码行数可能更有意义;
本文的解决方案针对以上的假定进行。
02 Go 语言实现
先看最简单的。
纯英文
根据以上分析,如果文章只包含普通文本且是英文,也就是说,每个字(单词)根据空格分隔,统计是最简单的。
func TotalWords(s string) int { n := 0 inWord := false for _, r := range s {