BinarySearch限制范围内的数字

时间:2012-01-18 15:20:17

标签: c# binary-search

这是我的代码:

SortedDictionary<int,int> Numbers = new SortedDictionary<int,int>();
List<int> onlyP = new List<int>(Numbers.Keys);
int Inferior = int.Parse(toks[0]);
int Superior = int.Parse(toks[1]);
int count = 0;

int inferiorindex = Array.BinarySearch(Numbers.Keys.ToArray(), Inferior);
if (inferiorindex < 0) inferiorindex = (inferiorindex * -1) - 1;
int superiorindex = Array.BinarySearch(Numbers.Keys.ToArray(), Superior);
if (superiorindex < 0) superiorindex = (superiorindex * -1) - 1;

count = Numbers[onlyP[superiorindex]] - Numbers[onlyP[inferiorindex]];

所以我要做的就是:我有一个排序字典,其中power为键,而正常迭代为值。我要打印在指定范围内适合多少个键。

实施例: dict的一些条目:[1,1],[4,2],[8,3],[9,4],[16,5],[25,6],[27,7],[32 ,8] 限制:2和10 数字在2 - 10:4,8,9 = 3个数字内。

使用BinarySearch我试图快速找到我想要的数字,然后减去Potencias [onlyP [superiorindex]] - Potencias [onlyP [inferiorindex]]来查找该范围内有多少个数字。不幸的是,它并不适用于所有情况,有时它的数量少于实际数量。怎么解决这个问题?提前谢谢。

[编辑]问题的例子:如果我选择限制:4和4 ...它返回0,但答案是1。 限制:1和10 ^ 9(整个范围)返回32669 ......但答案是32670。 该算法忽略了权力。

3 个答案:

答案 0 :(得分:4)

最后,阅读了文档。注意upperIndex转换的-1和返回值的+1,这些很重要。

var numbers = new[] { 1, 4, 8, 9, 16, 25, 27, 32 };

var lowerBound = 4;
var upperBound = 17;

int lowerIndex = Array.BinarySearch(numbers, lowerBound);
if (lowerIndex < 0) lowerIndex = ~lowerIndex;

// - 1 here because we want the index of the item that is <= upper bound.
int upperIndex = Array.BinarySearch(numbers, upperBound);
if (upperIndex < 0) upperIndex = ~upperIndex - 1;

return (upperIndex - lowerIndex) + 1;

<强>解释

对于较低的索引,我们只需要补码,因为BinarySearch返回第一项&gt; = lowerBound的索引。

对于上面的索引,我们还从补码中减去一个,因为我们想要第一个项目&lt; = upperBound(不是&gt; = upperBound,这是BinarySearch返回的内容)。

答案 1 :(得分:2)

似乎你没有用它来做后处理二进制搜索返回值的正确方法: http://msdn.microsoft.com/en-us/library/5kwds4b1.aspx

应该是: if (inferiorindex < 0) inferiorindex = ~inferiorindex;

(未测试的)

此外,List支持二进制搜索,因此您不必执行Array.BinarySearch操作,只需处理onlyP

答案 2 :(得分:2)

int inferiorindex = Array.BinarySearch<int>(keys, Inferior);
if (inferiorindex < 0) {
    inferiorindex = ~inferiorindex;
}

int superiorindex = Array.BinarySearch<int>(keys, Superior);
if (superiorindex < 0) {
    // superiorindex is the binary complement of the next higher.
    // -1 because we want the highest.
    superiorindex = ~superiorindex - 1;
}

int count = superiorindex - inferiorindex + 1;