gpt4 book ai didi

c# - 在一个字节中找到设置位的位置

转载 作者:行者123 更新时间:2023-12-05 02:24:01 25 4
gpt4 key购买 nike

我很想像 nVidia 的人一样创建一个稀疏的八叉树实现 ("Efficient Sparse Voxel Octrees")当我遇到这个问题时正在为他们的体素做事:

我有一个字节类型的位域(所以只有 8 位),它告诉我八叉树的叶子在哪里(1 表示叶子,0 表示没有叶子,附加 8 个节点 --> 8 位)。我现在想要做的是返回一个叶位置数组。我当前的实现是使用一个 while 循环来查明是否设置了 LSB。之后输入移位 1。所以我是这样做的:

int leafposition = _leafmask & _validmask;
int[] result = new int[8];
int arrayPosition = 0;
int iteration = 0;
while ( leafposition > 0 )
{
iteration++; //nodes are not zero-indexed ... ?
if ( (leafposition & 1) == 1 ) // LSB set?
{
result.SetValue( iteration, arrayPosition );
arrayPosition++;
};
leafposition = leafposition >> 1;
}
return result;

这看起来并不优雅,有两点令人不安:

  • 这个 while 循环模仿了 for 循环
  • 结果数组很可能会小于 8 个值,但调整大小的代价很高

我希望结果类似于 [2,4,6] for 42 (0010 1010)

谁能提供一个更优雅且仍然可读的解决方案?


结果

我正在使用我之前实现的八叉树叶计数函数将数组设置为适当的大小。

最佳答案

如果你追求代码简洁,我会使用这个:

int[] result = new int[8]; 
byte leafposition = 42;
int arrayPosition = 0;
for (int iteration = 0; iteration < 8; ++iteration)
if ((leafposition & (1 << iteration)) != 0)
result[arrayPosition++] = iteration + 1; // one-indexed

如果您追求性能,我会使用预先填充的数组(包含 256 个条目)。您可以静态地(在编译时)或延迟地(在第一次调用您的方法之前)生成它。

int[][] leaves =
{
/* 00000000 */ new int[] { },
/* 00000001 */ new int[] { 1 },
/* 00000010 */ new int[] { 2 },
/* 00000011 */ new int[] { 1, 2 },
/* 00000100 */ new int[] { 3 },
/* 00000101 */ new int[] { 1, 3 },
/* 00000110 */ new int[] { 2, 3 },
/* 00000111 */ new int[] { 1, 2, 3 },
/* 00001000 */ new int[] { 4 },
/* 00001001 */ new int[] { 1, 4 },
/* ... */
};

byte leafposition = 42;
int[] result = leaves[leafposition];

编辑:如果您正在使用查找表并且可以负担得起一次性初始化(这将通过多次后续使用分摊),我建议动态创建它(而不是膨胀你的源代码)。这是 LINQ 中的一些示例代码;您可以改用循环版本。

int[][] leaves = new int[256][];
for (int i = 0; i < 256; ++i)
leaves[i] = Enumerable.Range(0, 8)
.Where(b => (i & (1 << b)) != 0)
.Select(b => b + 1)
.ToArray();

关于c# - 在一个字节中找到设置位的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16637439/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com