栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在int中找到第n个SET位

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在int中找到第n个SET位

事实证明,确实可以无循环执行此操作。预计算此问题的(至少)8位版本最快。当然,这些表会占用高速缓存空间,但是在几乎所有现代PC方案中,仍然应该有净加速。在此代码中,n
= 0返回最低设置位,n = 1倒数第二,以此类推。

__popcnt解决方案

有一个使用__popcnt内在函数的解决方案(您需要__popcnt才能非常快,否则通过简单循环解决方案获得的任何性能提升都是没有意义的。幸运的是,大多数SSE4
+时代的处理器都支持它)。

// lookup table for sub-problem: 8-bit vbyte PRECOMP[256][8] = { .... } // PRECOMP[v][n] for v < 256 and n < 8ulong nthSetBit(ulong v, ulong n) {    ulong p = __popcnt(v & 0xFFFF);    ulong shift = 0;    if (p <= n) {        v >>= 16;        shift += 16;        n -= p;    }    p = __popcnt(v & 0xFF);    if (p <= n) {        shift += 8;        v >>= 8;        n -= p;    }    if (n >= 8) return 0; // optional safety, in case n > # of set bits    return PRECOMP[v & 0xFF][n] << shift;}

这说明了分而治之方法是如何工作的。

通用解决方案

还有一种针对“通用”体系结构的解决方案-不使用__popcnt。可以通过处理8位块来完成。您还需要一个查找表来告诉您一个字节的popcnt:

byte PRECOMP[256][8] = { .... } // PRECOMP[v][n] for v<256 and n < 8byte POPCNT[256] = { ... } // POPCNT[v] is the number of set bits in v. (v < 256)ulong nthSetBit(ulong v, ulong n) {    ulong p = POPCNT[v & 0xFF];    ulong shift = 0;    if (p <= n) {        n -= p;        v >>= 8;        shift += 8;        p = POPCNT[v & 0xFF];        if (p <= n) { n -= p; shift += 8; v >>= 8; p = POPCNT[v & 0xFF]; if (p <= n) {     n -= p;     shift += 8;     v >>= 8; }        }    }    if (n >= 8) return 0; // optional safety, in case n > # of set bits    return PRECOMP[v & 0xFF][n] << shift;}

当然,这可以通过循环来完成,但是展开形式更快,并且异常形式的循环会使编译器不太可能为您自动展开它。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/391223.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号