新手问题 字符串截取后面

ane · 2017年07月05日 · 最后由 saiga 回复于 2017年07月05日 · 6004 次阅读

今天看到一段 erlang 代码,大致功能就是输入“xxxx.erl”或者“xxxx”的字符串。截取其中的“.erl”,来进行判断是否是 erlang 源文件

-define(EXT, ".erl").

 lists:reverse(string:sub_string(lists:reverse(Str), 1, length(?EXT))).

代码的思路也只是先把字符串先 reverse 成“lre.xxxx”,再截取 [1..".erl".length],然后再 reverse 成“.erl”。

这种先 reverse 再截取,再 reverse 的方式,不是很清楚,会是从遍历字符串效率角度考虑的吗?发个问题,想让大家多提点思路吧

以前一些算法题类似于字符串首部移到尾部,到是这样的思路方式。

如果你只想判断结尾的扩展名,并且通过字符串操作而不是构造个 File 对象啥的

[1] pry(main)> "yooo.erl".end_with?(".erl")
=> true
[2] pry(main)> "yooo.erl".end_with?(".rb")
=> false
jasl 回复

没错,我一般也是这样处理的,我就是不明白这段 erlang 代码作者这样写的目的,也许是不确定字符串长度,才这样写的?

ane 回复

不知道...开始没认真读正文。

我也不太能理解一个可以很直觉的解决的问题为啥要用这么深奥的算法来解决...

erlang 菜鸟,无责任瞎说:因为 erlang 实现里字符串是用链表实现的,length 等操作是 O(n) 复杂度,reverse 之后处理前面部分,比后面效率高?

这个需要看 string:sub_string/3lists:reverse/1 的实现。

首先是 string:sub_string, 这个函数通过 cons 递归截取。erlang 实现

然后就是 lists:reverse/1,这个函数虽然也是 erlang 实现,但是主要通过 lists:reverse/2 实现 reverse,而后者是 bif,也就是性能会比使用 erlang 实现的函数高上许多。大概就是这样

需要 登录 后方可回复, 如果你还没有账号请 注册新账号