有人来讨论技术吗?如何高效的将字符串中的大小写互换?

2020-01-29 21:13:18 +08:00
 GDC
例如,输入 abcXYZhello123 输出 ABCxyzHELLO123 ;

就是把字符串中的大写全换成小写、小写全换成大写。

除了逐个字符判断+替换,还有什么更快速高效的方法吗?

不限语言,最好是 php 或 js 的,仅仅提供思路讨论也行。
5208 次点击
所在节点    程序员
37 条回复
Chingim
2020-01-29 21:16:24 +08:00
每个字符肯定都要处理一遍, 所以 O(n) 的时间复杂度少不了
fengtons
2020-01-29 21:16:25 +08:00
通过 ascii 码判断并加减完成转换?
rigortek
2020-01-29 21:20:53 +08:00
正则表达式
ahhui
2020-01-29 21:23:23 +08:00
ascii 码,一遍循环,<x 的话+x,>x 的话-x,很容易。查下 ascii table 就知道 x 是几了
GDC
2020-01-29 21:23:41 +08:00
@rigortek 也想过正则,没想明白怎么整,能详细点吗
Mithril
2020-01-29 21:25:08 +08:00
如果是兼容 ASCII 编码的字符串直接位运算就可以。
KentY
2020-01-29 21:27:00 +08:00
我会用 ascii code 的方法. 有兴趣可以看看 vim 实现的"~"
GDC
2020-01-29 21:27:03 +08:00
@Mithril 都是 ASCII 编码,就是 base64 后的字符
ysc3839
2020-01-29 21:36:45 +08:00
应该没有了,用普通的方法,编译器会优化好的。
https://www.programmingsimplified.com/c/program/c-program-change-case

不过刚刚在 https://godbolt.org/ 试了一下,用 ctype.h 的 isupper islower toupper tolower,编译出来并没有内联,而是 call 这几个函数。觉得 call 影响性能的话还是直接写判断和加减比较好。
tonytonychopper
2020-01-29 21:42:36 +08:00
用啥方法都是 O(n),而且像楼上说到,编译器会优化。
52coder
2020-01-29 22:22:36 +08:00
@ysc3839 赞同,使用 c 库里的 isupper 等函数没内联暂开的话,可以手写函数 inline,毕竟就判断个 ascii 码范围,应该可以实现内联。
JerryCha
2020-01-29 22:24:44 +08:00
那么有没有什么办法能保证每个字符都遍历到且时间复杂度小于 O(n)呢(比如说 O(logn))
Mithril
2020-01-29 22:25:34 +08:00
大写字符是 65~90,小写是 97~112
二进制是 0100 0001~0101 1010 和 0110 0001~0111 1010
比如
01010001A,变成
01100001a

你可以直接翻转第六位,就是异或个 0010 0000

这个 0010 0000 在 ASCII 里面代表空格,所以你直接异或一个空格就可以。当然你得首先判断它是字符。

ASCII 当初就是这么设计的,大小写基本都是对称的位置。
另外虽然 ASCII 用来编码字符,但是对应数字那部分都是 0011 开头的。你把这部分 mask 掉剩下的就是字符所表示的实际数值。

兼容的 UTF8 也是一样的。不过正常来说,你要做一个完美的大小写转换,需要先判断 culture 才行。不过简单的可以就这么直接做了。
thedrwu
2020-01-29 23:08:04 +08:00
希腊字母?
带 accent/umlaut 的字母?
不知道 tr 能不能做。至少 vim 里的~可以完美转换。
wangyzj
2020-01-29 23:10:42 +08:00
ascii 吧
Believer
2020-01-29 23:13:40 +08:00
ascii table
Bromine0x23
2020-01-29 23:16:30 +08:00
@JerryCha 每个字符都遍历到 ≡ 时间复杂度至少是 O(n)
zhx1991
2020-01-29 23:27:53 +08:00
?

需要遍历就是 O(n) 的
msg7086
2020-01-29 23:29:16 +08:00
你都说了遍历了,比 O n 小的是跳着历。
@JerryCha
imn1
2020-01-29 23:45:07 +08:00
位运算
if (ch & 32)
ch = ch & 223
else
ch = ch | 225

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/640883

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX