我有一个排序的字符串数组。 鉴于识别的前缀字符串,我执行两个二进制搜索找到数组中包含以该前缀开头的单词的第一个和最后的位置:为什么(“abc”+ char.MaxValue).CompareTo(“abc”)== 0?
string [] words = {"aaa","abc","abcd","acd"};
string prefix = "abc";
int firstPosition = Array.BinarySearch<string>(words, prefix);
int lastPosition = Array.BinarySearch<string>(words, prefix + char.MaxValue);
if (firstPosition < 0)
firstPosition = ~firstPosition;
if (lastPosition < 0)
lastPosition = ~lastPosition;
运行这段代码中,我得到firstPosition和一位置都等于为1,而正确的答案是让lastPosition等于3(即指向第一个不匹配的单词)。 的二分查找方法使用CompareTo方法来比较的对象,我发现,
("abc"+char.MaxValue).CompareTo("abc")==0
意味着这两个字符串被认为是相等的! 如果我更改代码
int lastPosition = Array.BinarySearch<string>(words, prefix + "z");
我得到正确的答案。 而且我发现,
("abc"+char.MaxValue)==("abc")
正确的(相对于我的需要)返回false。
你能帮我解释一下CompareTo方法的行为吗?
我想让CompareTo方法的行为像==一样,以便BinarySearch方法为lastPosition返回3。
无论BinarySearch在这里使用什么(fe'string.IndexOf'或'CompareTo')。它忽略了'Char.MaxValue'的十六进制值。在[** Jon Skeets博客**](http://csharpindepth.com/Articles/General/strings.aspx)中搜索'ignore',你会发现它是可能的。从[MSDN](http://msdn.microsoft.com/en-us/library/35f0x18w。aspx):_“CompareTo方法被设计用于排序或字母排序操作,当方法调用的主要目的是确定两个字符串是否相等时,不应使用它。要确定两个字符串是否相等,请调用等于方法。“_ –
这段代码是更通用的函数的一部分,它对不同的数据类型执行”范围“搜索,前提是搜索的对象实现IComparable。出于这个原因,尽管二分查找是一个灵活的解决方案,但使用诸如前缀树等文本专用数据结构并不适合于此目的。我认为一个可以解决灵活性问题的解决方案是将字符串类型封装到一个在其CompareTo方法中实现“正确”比较的类型中。 – Esuli