简体   繁体   English

在 std::bitset 中查找设置为 true 的最高索引

[英]Find the highest index set to true in std::bitset

I'm using std::bitset<9> deck in my program.我在我的程序中使用std::bitset<9> deck By default it initializes all bits to 0.默认情况下,它将所有位初始化为 0。

Somewhere in my code I'm doing: deck.flip(index) where index can be any number from 0-8 (bitset indexes).在我的代码中某处我正在做: deck.flip(index)其中index可以是0-8之间的任何数字(位集索引)。

Now what I need is to find the index of the last bit set to true .现在我需要找到设置为truelast一位的索引。

Eg:例如:

000100010 - bitset
876543210 - index

In this example the latest bit set to true is at index 5 .在此示例中,设置为 true 的最新位位于索引5处。 That is what I would like to find using std::bitset .这就是我想使用std::bitset找到的。

I have read the documentation https://en.cppreference.com/w/cpp/utility/bitset and found no useful function to do this, and as a beginner I'm having a hard time figuring out, how can I do this?我已阅读文档https://en.cppreference.com/w/cpp/utility/bitset并发现没有有用的 function 可以做到这一点,作为初学者,我很难弄清楚,我该怎么做?

(Sorry if question is poorly written, english is my second language) (对不起,如果问题写得不好,英语是我的第二语言)

It seems that only option is to iterate over bit set and find last bit set since bit set does not have support for iterators.似乎唯一的选择是迭代位集并找到最后一个位集,因为位集不支持迭代器。

#include <iostream>
#include <bitset>
#include <optional>

template <size_t N>
constexpr std::optional<int> find_last_index_of_bit_set(std::bitset<N> set)
{
    for (int i = set.size()-1; i > -1; --i) {
      if (set.test(i)) {
          return std::optional(i);
      }
    }
    return std::nullopt;
}

int main() 
{
    std::bitset<10> bitSet("000100010");

    auto pos = find_last_index_of_bit_set(bitSet);

    if (pos.has_value()) {
        std::cout << "Max index is: " << pos.value() << '\n';
    } else {
        std::cout << "No bit set";
    }
}

Here's a gcc/clang specific way using the __builtin_clzl() intrinsic, which returns the number of leading 0 bits starting from the most significant:这是使用__builtin_clzl()内在函数的 gcc/clang 特定方式,它返回从最高有效位开始的前导 0 位的数量:

#include <bitset>
#include <cassert>
#include <climits>
#include <iostream>

template<std::size_t N>
int msb(const std::bitset<N> &bs) {
  static_assert(N <= (CHAR_BIT * sizeof(unsigned long)), "bitset is too big");
  auto n = bs.to_ulong();
  // C++20 will have std::countl_zero() but in the meantime:
  assert(n != 0); // clz is undefined if n is 0. Maybe return -1 in this case?
  return (CHAR_BIT * sizeof n) - __builtin_clzl(n) - 1;
}

int main() {
  std::bitset<9> bs;
  bs[1] = 1;
  bs[5] = 1;
  std::cout << "Highest set bit is " << msb(bs) << '\n';
  return 0;
}

will print Highest set bit is 5 .将打印Highest set bit is 5 This approach only works with bitsets equal or smaller than the number of bits in an unsigned long , of course (Though it can go up to unsigned long long with a few minor changes)当然,这种方法仅适用于等于或小于unsigned long中位数的位集(尽管它可以 go 达到unsigned long long并进行一些小的更改)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM