C# 位模式中真值的前n个位置
我有一个100位的位模式。程序将改变模式中的位为真或假。在任何给定的时间,我都需要找到第一个“n”真值的位置。例如,如果模式如下 10011001000 位为真的前3个索引是0、3、4 位为真的前4个索引是0、3、4、7 我可以有一个列表,但是firstntrue(int)的复杂性将是O(n)。是否有改进性能的方法?没有 当然,除非您在更改发生时截取更改,并维护“前100个”列表。否C# 位模式中真值的前n个位置,c#,C#,我有一个100位的位模式。程序将改变模式中的位为真或假。在任何给定的时间,我都需要找到第一个“n”真值的位置。例如,如果模式如下 10011001000 位为真的前3个索引是0、3、4 位为真的前4个索引是0、3、4、7 我可以有一个列表,但是firstntrue(int)的复杂性将是O(n)。是否有改进性能的方法?没有 当然,除非您在更改发生时截取更改,并维护“前100个”列表。否 当然,除非您在发生更改时截取它们,并维护“前100个”列表。不,没有办法改进O(n)。这可以从数学上证明不,没有
当然,除非您在发生更改时截取它们,并维护“前100个”列表。不,没有办法改进O(n)。这可以从数学上证明不,没有办法提高O(n)。这可以从数学上证明没有额外的数据结构,复杂性就无法降低,因为在最坏的情况下,您需要扫描整个列表。没有额外的数据结构,复杂性就无法降低,因为在最坏的情况下,您需要扫描整个列表。对于“n”项,您最多必须检查“n”次,即O(n)!
如果不进行任何拦截,也不知道它们是如何变化的,你怎么能期望减少这种情况?!对于“n”项,你最多要检查“n”次,即O(n)!
如果不进行任何拦截,也不知道它们是如何变化的,你怎么能期望降低这种复杂性呢?不,如果你只有一个普通数组,你就无法提高复杂性 如果只有很少的1:s到很多的0:s,则可以通过一个常数因子来提高性能,但仍然是O(n) 如果可以将位数组视为字节数组(甚至是int32数组),则可以在检查每个位之前检查每个字节(如果字节>0)
如果1位小于1:8,则可以将其实现为稀疏数组,而不是存储所有1:s的索引。否,如果只有普通数组,则无法提高复杂性 如果只有很少的1:s到很多的0:s,则可以通过一个常数因子来提高性能,但仍然是O(n) 如果可以将位数组视为字节数组(甚至是int32数组),则可以在检查每个位之前检查每个字节(如果字节>0)
如果小于1:8的1位,可以将其实现为一个稀疏数组,而不是存储所有1:s的索引的
List
。我假设在搜索时列表没有改变,但它会一直改变,直到你决定搜索,然后你就开始做你的事情
每个字节有2^8=256个0和1的组合。这里有100/8=13个字节要检查
因此,您可以构建一个包含256个条目的查找表。键是您正在位流中检查的字节的当前实际值,值是您查找的数据(一个包含1位位置的元组)。因此,如果给它5,它将返回{0,2}。此查找的成本是恒定的,内存使用量非常小
现在,当您遍历位流时,您可以一次处理一个字节的数据(而不是一次处理一个字节),只需跟踪当前字节数(当然从0开始),并将8*当前字节数添加到返回的元组中的值中。因此,现在您基本上将问题简化为O(n/8)通过使用预先计算的查找表
您可以构建更大的查找表以获得更快的速度,但这将占用更多内存
虽然我无法想象n=100的O(n)算法会对您造成性能问题。除非您在某个内部循环中经常调用它?我假设列表在您搜索时不会更改,但它会一直更改,直到您决定搜索,然后您再执行您的操作 每个字节有2^8=256个0和1的组合。这里有100/8=13个字节要检查 因此,您可以构建一个包含256个条目的查找表。键是您正在位流中检查的字节的当前实际值,值是您查找的数据(一个包含1位位置的元组)。因此,如果给它5,它将返回{0,2}。此查找的成本是恒定的,内存使用量非常小 现在,当您遍历位流时,您可以一次处理一个字节的数据(而不是一次处理一个字节),只需跟踪当前字节数(当然从0开始),并将8*当前字节数添加到返回的元组中的值中。因此,现在您基本上将问题简化为O(n/8)通过使用预先计算的查找表 您可以构建更大的查找表以获得更快的速度,但这将占用更多内存
尽管我无法想象n=100的O(n)算法确实会给您带来一些性能问题。除非您在某个内部循环中经常调用它?正如其他人所说,在没有进一步结构的情况下查找n个最低设置位是O(n)操作 如果您希望提高性能,您是否考虑过问题的实现方面 在我的头顶上,q&~(q-1)将只保留数字q中设置的最低位,因为从任何二进制数中减去1将填充从右边到设置的第一个数字的1s,将该数字更改为0,并保留其余数字。在设置了1位的数字中,向右移位并对零进行测试,可提供一个简单的测试,以区分是否存在潜在答案小于真实答案或大于或等于。因此,您可以从那里进行二进制搜索 要找到下一个,请删除最低的数字,并使用较小的初始二进制搜索窗口。可能有更好的解决方案,但这应该比从最小到最大检查每一位并检查是否已设置好要好 这种实现方式不会影响复杂性,但可能有助于提高性能。与其他实现方式一样