这个问题有啥好的位运算写法?

FancyMouse 2013-10-14 09:41:14
先写一个我的naive版本:

uint64 transform(uint64 value, uint64 mask)
{
int c = 0;
uint64 result = 0;
for(int i=0, c=0;i<64;i++)
if(mask & (1ull<<i))
result |= ((value>>i) & 1)<<c++;
return result;
}

也就是说,mask提供需要提取的bit掩码,然后把value里掩码出来的bit给压缩到低k位里,k是mask里1的个数。
一个例子是:value: 110011, mask: 010111,那么返回1011
naive的写法人人会写。我的问题是,这个有啥更好的写法吗?比如可以像popcnt一样用log(n)次迭代来代替这里的线性迭代。我不知道这里能不能做类似的事情。
...全文
353 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
lunat 2013-11-02
  • 打赏
  • 举报
回复
这个可以考虑一下局部查表法。 uint8_t values[65536]; uint8_t counts[256] for (int i = 0; i < 256; i++) for (int j = 0; j < 256; j++) values[(i << 8) | j] = transform8(i, j);//transform8:8位版本的transform
lm_whales 2013-11-02
  • 打赏
  • 举报
回复
最后一个是 x = (x & 0x000000ffff) + ((x& 0xffff0000) > 16);
lm_whales 2013-11-02
  • 打赏
  • 举报
回复
统计1的个数 写个 32Bits的 x = (x & 0x55555555) + ((x& 0xaaaaaaaa) > 1); x = (x & 0x33333333) + ((x& 0xcccccccc) > 2); x = (x & 0x0f0f0f0f) + ((x& 0xf0f0f0f0) > 4); x = (x & 0x0000ff00ff) + ((x& 0xff00ff00) > 8); x = (x & 0x000000ffff) + ((x& 0xffff0000) > 8);
赵4老师 2013-10-14
  • 打赏
  • 举报
回复
profiler
图灵狗 2013-10-14
  • 打赏
  • 举报
回复
这个写法效率已经相当的高,只能稍作修改:

uint64 transform2(uint64 value, uint64 mask)
{
	uint64 result = 0;
	uint64 bm = 1;
	int c = 0;
  
	for(int i = 0; i < 64; i++)
	{
    		if(mask & bm) result |= ((value >> i) & 1) << c++;
		bm <<= 1;
	}

	return result;
}
引用 楼主 FancyMouse 的回复:
先写一个我的naive版本:

uint64 transform(uint64 value, uint64 mask)
{
  int c = 0;
  uint64 result = 0;
  for(int i=0, c=0;i<64;i++)
    if(mask & (1ull<<i))
      result |= ((value>>i) & 1)<<c++;
  return result;
}
也就是说,mask提供需要提取的bit掩码,然后把value里掩码出来的bit给压缩到低k位里,k是mask里1的个数。 一个例子是:value: 110011, mask: 010111,那么返回1011 naive的写法人人会写。我的问题是,这个有啥更好的写法吗?比如可以像popcnt一样用log(n)次迭代来代替这里的线性迭代。我不知道这里能不能做类似的事情。
dianyancao 2013-10-14
  • 打赏
  • 举报
回复
删除数组中的几个指定元素,最坏情况下应该是O(n)

3,882

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧