#include #include #include #include #include #include

Is there a more elegant way to convert a two-state string into a bitset than just by a 'for' loop?

1.9k views Asked by At

I wrote this code snippet to convert a two-state string ("+++--+-" or "yynnny") into a std::bitset:

#include <bitset>
#include <cstddef>
#include <string>
#include <iostream>

std::bitset<70> convertTwoStateString(std::string twoState)
{
    std::bitset<70> a{0b0};
    std::bitset<70> eins{0b1};

    for(const auto c : twoState) {
        if(c == '+') {
            a <<= 1;
            a |= eins;
        }
        if(c == '-') {
            a <<= 1;
        }
    }
    return a;
}


int main()
{
    std::string s{"-+--+++--+--+"};
    std::bitset<70> set = convertTwoStateString(s);

    std::cout << set << std::endl;
    //0000000000000000000000000000000000000000000000000000000000100111001001
}

Is there a more algorithmic and/or elegant way to do such a conversion?

2

There are 2 answers

0
康桓瑋 On BEST ANSWER

The std::bitset constructor can specify alternate characters representing 0/1, so you can

std::string s{"-+--+++--+--+"};
std::bitset<70> set(s, 0, s.size(), '-', '+');

Demo

7
Pepijn Kramer On

Fun fact, bitset is not needed and the whole parsing can even be done at compile time if you want.

#include <cstdint>
#include <utility>
#include <stdexcept>
#include <type_traits>

template<std::size_t N>
static constexpr auto parse_bin(const char zero, const char one, const char(&string)[N]) 
{
    static_assert(N <= 8 * sizeof(std::uint32_t));
    static_assert(N > 1);

    std::uint32_t retval{};
    std::uint32_t mask = 1 << (N-2);
    std::size_t index{0ul};
   
    while(string[index] != 0)
    {
        auto c = string[index];
        if ((c != zero) && (c != one))
        {
            throw std::invalid_argument{"invalid input character"};
        }

        if (c == one) retval |= mask;
        mask >>= 1;
        ++index;
    }
    return retval;
}

int main()
{
    static_assert(5 == parse_bin('0', '1', "101"));
    static_assert(9 == parse_bin('-', '+', "+--+"));
    static_assert(17 == parse_bin('n', 'y', "ynnny"));

    return 0;
}