字符串比较中NSNumericSearch选项的工作原理
栏目: Objective-C · 发布时间: 5年前
内容简介:相信研究过怎么在 ObjC 中进行版本字符串比对的朋友,大多都看过这一篇 StackOverflow 的问答:里面提到的
相信研究过怎么在 ObjC 中进行版本字符串比对的朋友,大多都看过这一篇 StackOverflow 的问答:
Compare version numbers in Objective-C
里面提到的 [versionStrA compare:versionStrB options:NSNumericSearch]
的方案应该是最优雅的方案了。
但是不理解这个 NSNumericSearch 的具体工作原理就去盲目使用是危险的,今天我就来研究下它的具体工作原理。
官方文档
参照 官方文档 里的说明:
Numbers within strings are compared using numeric value, that is, Name2.txt < Name7.txt < Name25.txt. Numeric comparison only applies to the numerals in the string, not other characters that would have meaning in a numeric representation such as a negative sign, a comma, or a decimal point.
粗略的直译一下:
在字符串中的数字将被用数值进行比较,就是说,Name2.txt < Name7.txt < Name25.txt。 数值比较仅仅对字符串中的纯数字(0-9)生效,而不对其它在数字表达中含有意义的字符生效,例如负号,逗号或小数点。
这段说明略有歧义,导致很多人第一次看的时候被绕晕。例如刚刚那篇 StackOverflow 问答里的 dooleyo 就理解成 "1.2.3"
和 "1.1.12"
进行比较时,会抛弃所有非数字的字符变成 123
和 1112
进行比较,最后得到 "1.2.3" < "1.1.12"
的结论。问答里不少其它朋友也有类似的想法。
探求真相
真相只有经过实验才能得到,所以写了一些测试代码来试一下具体的结果:
- (void)testExample { [self compareString:@"1.2.3" andString:@"1.1.12"]; [self compareString:@"1.8" andString:@"1.7.2.3.55"]; [self compareString:@"1.44" andString:@"1.5"]; [self compareString:@"7.4.1" andString:@"7.5"]; } - (void)compareString:(NSString *)stringA andString:(NSString *)stringB { NSComparisonResult result = [stringA compare:stringB options:NSNumericSearch]; switch (result) { case NSOrderedDescending: NSLog(@"%@ > %@", stringA, stringB); break; case NSOrderedAscending: NSLog(@"%@ < %@", stringA, stringB); break; default: NSLog(@"%@ = %@", stringA, stringB); break; } }
得到的结果是:
1.2.3 > 1.1.12 1.8 > 1.7.2.3.55 1.44 > 1.5 7.4.1 < 7.5
看上去结果都是正确的,那么看来 NSNumericSearch
并不是粗暴的去掉所有非数字字符后进行数值比对。
结合原回答里答主说的一句话: keeping in mind that "1" < "1.0" < "1.0.0"
,忽然想到了一些什么,继续进行下一步的实验,得到的结果如下:
1 < 1.0 1.0 < 1.0.0 a10 < b2 a2 < b10 c10 > b2 c2 > b10 2a < 10b 10a > 2b 2c < 10b 10c > 2b
大家看到这里应该可以猜到官方文档的意思是什么了,其实文档的意思是整个字串 非数字的部分仍然进行常规的字符比较逻辑,只有在遇到数字的时候会把连续的数字转换成数值再进行比对 。具体的比较过程示例参照下图:
这时候一些奇特的比对结果就可以解释明白了,比如使用这种比较模式会得出 "01" = "1"
。
继续深入
那么还剩下一个问题,如果和数字字符比较的是非数字字符,会怎么样?我们可以挑一些 ASCII 码在数字字符周围的字符进行试验,结果如下:
a/c < a100c a:c > a100c a/c < a1c a:c > a1c
注意这里出现的部分字符 ASCII 码为:
/ = 47 0 = 48 1 = 49 ... 9 = 57 : = 58
可以看出现了比较的字符一边是数字,一边是非数字时,是按照常规的 ASCII 码进行比对的。
总结
那么分析到这里就基本结束了,剩下的一些场景类推一下都很容易理解。
其实在各大 OS 里的文件系统下文件 排序 用的就是这种比较方法,一开始没有想到这点所以理解上绕了一些弯路。
用 NSNumericSearch
来进行版本字符串的比对也是十分有效的,不是特殊需要的话就再也不用傻傻的自己分割字符串再分段比较啦。
以上所述就是小编给大家介绍的《字符串比较中NSNumericSearch选项的工作原理》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 查找一个字符串中最长不含重复字符的子字符串,计算该最长子字符串的长度
- 字符串、字符处理总结
- 高频算法面试题(字符串)leetcode 387. 字符串中的第一个唯一字符
- php删除字符串最后一个字符
- (三)C语言之字符串与字符串函数
- 算法笔记字符串处理问题H:编排字符串(2064)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Ruby Cookbook
Lucas Carlson、Leonard Richardson / O'Reilly Media / 2006-7-29 / USD 49.99
Do you want to push Ruby to its limits? The "Ruby Cookbook" is the most comprehensive problem-solving guide to today's hottest programming language. It gives you hundreds of solutions to real-world pr......一起来看看 《Ruby Cookbook》 这本书的介绍吧!