How to check whether only 2 bits in a vector of bits at a specific position are on (edge‑case‑safe) with C++

1 Answer

0 votes
#include <iostream>
#include <string>
#include <vector>

// Checks whether a binary string has *exactly two '1' bits*
// and they appear *only* at positions p1 and p2 (0‑based from the right).
bool exactTwoBitsAt(const std::string& bin, int p1, int p2) {
    // Basic sanity checks: positions must be non-negative and string must not be empty
    if (p1 < 0 || p2 < 0 || bin.empty())
        return false;

    // The two positions must be distinct; otherwise you can't have two separate bits
    if (p1 == p2)
        return false;

    const int n = static_cast<int>(bin.size());

    // Positions must be within the range of the binary string
    if (p1 >= n || p2 >= n)
        return false;

    int onesCount = 0;

    // Scan the string from left to right
    for (int i = 0; i < n; ++i) {
        char c = bin[i];

        // Only '0' and '1' are valid characters
        if (c != '0' && c != '1')
            return false;

        if (c == '1') {
            // Convert index-from-left to index-from-right (0-based)
            int posFromRight = n - 1 - i;

            // If the '1' is at one of the allowed positions, count it
            if (posFromRight == p1 || posFromRight == p2) {
                ++onesCount;
            } else {
                // A '1' outside the two specified positions invalidates the string
                return false;
            }
        }
    }

    // Valid only if exactly two '1' bits were found
    return onesCount == 2;
}

int main() {
    struct Test {
        std::string bin;
        int p1, p2;
    };

    // Test cases demonstrating both valid and invalid scenarios
    std::vector<Test> tests = {
        {"1000010000", 4, 9}, // true
        {"0010000010", 1, 7}, // true
        {"0000100100", 2, 5}, // true

        {"1000010000", 3, 9}, // false - wrong position
        {"1001010000", 4, 9}, // false - extra '1'
        {"1111111111", 4, 9}, // false - too many '1's
        {"0000000000", 4, 9}, // false - no '1's
        {"1000010000", 4, 8}, // false - one bit in wrong place
        {"1",          0, 0}, // false - needs two distinct bits
        {"1",          0, 1}, // false - out of range
        {"",           1, 1}, // false - empty string
    };

    for (const auto& t : tests) {
        bool result = exactTwoBitsAt(t.bin, t.p1, t.p2);
        std::cout << t.bin << "  bits (" << t.p1 << ", " << t.p2 << ")  ->  "
                  << (result ? "true" : "false") << "\n";
    }
}


/*
OUTPUT:

1000010000  bits (4, 9)  ->  true
0010000010  bits (1, 7)  ->  true
0000100100  bits (2, 5)  ->  true
1000010000  bits (3, 9)  ->  false
1001010000  bits (4, 9)  ->  false
1111111111  bits (4, 9)  ->  false
0000000000  bits (4, 9)  ->  false
1000010000  bits (4, 8)  ->  false
1  bits (0, 0)  ->  false
1  bits (0, 1)  ->  false
  bits (1, 1)  ->  false

*/

 



answered Apr 3 by avibootz
edited Apr 3 by avibootz

Related questions

...