2012-01-18 132 views
1

数二分查找范围这是我的代码:的范围内

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]]; 

所以我想要做的是这样的:我有一个排序的字典,权力键,和一个正常的迭代的值。我必须打印在指定范围内有多少个键。字典中的一些条目:[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. 该算法忽略权力。

+0

如有任何问题,我会在这里回答。提前致谢。 – 2012-01-18 15:20:44

+0

对不起,一些代码丢失,只是编辑。 – 2012-01-18 15:24:22

+0

为什么它不只是superiorIndex - inferiorIndex?为什么在代码的最后一行查找字典? – 2012-01-18 15:29:31

回答

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; 

说明

对于较低指数,我们只取补,因为二分查找返回的第一个项目> =下界的索引。

对于上面的索引,我们还补充了一个补码,因为我们想要第一个项目< = upperBound(not> = upperBound这是BinarySearch的返回值)。

+0

这就是他使用BinarySearch的原因;-)如果搜索到的元素本身不存在,这就是为什么要获得集合中最近的项目。 – Seb 2012-01-18 16:02:03

+0

啊,我想我现在明白了这个问题,会更新我的答案。 – Joey 2012-01-18 16:04:13

+0

是的,限制可能会或可能不是一种力量,所以我使用二分查找。我尝试遍历字典,但与此方法相比较慢,我真的需要这种算法的速度。 – 2012-01-18 16:06:10

2

看来,你没有做它的赖特韦进行后处理的二进制搜索返回值: http://msdn.microsoft.com/en-us/library/5kwds4b1.aspx

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

(未经测试)

此外,名单支持二进制搜索,所以你不必做Array.BinarySearch的事情,只需在onlyP上工作。

+0

谢谢!我不知道列表支持BS。我只是修复它。 – 2012-01-18 16:09:19

+0

您是否尝试过按位运算符而不是'inferiorindex =(inferiorindex * -1) - 1'? – Seb 2012-01-18 16:18:02

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; 
+0

它终于奏效了!非常感谢!我必须更好地理解代码,因为说实话我有点困惑。 – 2012-01-18 16:44:44

+0

查看[Array.BinarySearch](http://msdn.microsoft.com/en-us/library/2cy9f6wb.aspx)的描述,并使用调试器来逐步分析代码。 – 2012-01-18 17:48:32