Generate all sequences of bits within Hamming distance t

后端 未结 4 1490
春和景丽
春和景丽 2020-12-04 03:22

Given a vector of bits v, compute the collection of bits that have Hamming distance 1 with v, then with distance 2, up to an input paramet

相关标签:
4条回答
  • 2020-12-04 03:38
    #include <stdio.h>
    #include <stdint.h>
    #include <string.h>
    
    void magic(char* str, int i, int changesLeft) {
            if (changesLeft == 0) {
                    printf("%s\n", str);
                    return;
            }
            if (i < 0) return;
            // flip current bit
            str[i] = str[i] == '0' ? '1' : '0';
            magic(str, i-1, changesLeft-1);
            // or don't flip it (flip it again to undo)
            str[i] = str[i] == '0' ? '1' : '0';
            magic(str, i-1, changesLeft);
    }
    
    int main(void) {
            char str[] = "011";
            printf("%s\n", str);
            size_t len = strlen(str);
            size_t maxDistance = len;
            for (size_t i = 1 ; i <= maxDistance ; ++i) {
                    printf("Computing for distance %d\n", i);
                    magic(str, len-1, i);
                    printf("----------------\n");
            }
            return 0;
    }
    

    Output:

    MacBook-Pro:hammingDist gsamaras$ nano kastrinis.cpp
    MacBook-Pro:hammingDist gsamaras$ g++ -Wall kastrinis.cpp 
    MacBook-Pro:hammingDist gsamaras$ ./a.out 
    011
    Computing for distance 1
    010
    001
    111
    ----------------
    Computing for distance 2
    000
    110
    101
    ----------------
    Computing for distance 3
    100
    ----------------
    
    0 讨论(0)
  • 2020-12-04 03:46

    In response to Kastrinis' answer, I would like to verify that this can be extended to my basis example, like this:

    #include <iostream>
    #include <vector>
    
    void print(std::vector<char>&v)
    {
        for (auto i = v.begin(); i != v.end(); ++i)
            std::cout << (int)*i;
        std::cout << "\n";
    }
    
    void magic(std::vector<char>& str, const int i, const int changesLeft) {
            if (changesLeft == 0) {
                    print(str);
                    return;
            }
            if (i < 0) return;
            // flip current bit
            str[i] ^= 1;
            magic(str, i-1, changesLeft-1);
            // or don't flip it (flip it again to undo)
            str[i] ^= 1;
            magic(str, i-1, changesLeft);
    }
    
    int main(void) {
            std::vector<char> str = {0, 1, 1};
            print(str);
            size_t len = str.size();
            size_t maxDistance = str.size();
            for (size_t i = 1 ; i <= maxDistance ; ++i) {
                    printf("Computing for distance %lu\n", i);
                    magic(str, len-1, i);
                    printf("----------------\n");
            }
            return 0;
    }
    

    where the output is identical.


    PS - I am also toggling the bit with a different way.

    0 讨论(0)
  • 2020-12-04 03:47

    First: There is a bijection between hamming dist k bit-vectors and subsets (of n aka v.size()) of kardinality k (the set of indices with changed bits). Hence, I'd enumerate the subsets of changed indices instead. A quick glance at the SO history shows this reference. You'd have to keep track of the correct cardinalitites of course.

    Considering efficiency is probably pointless, since the solution to your problem is exponential anyways.

    0 讨论(0)
  • 2020-12-04 03:59

    If Hamming distance h(u, v) = k, then u^v has exactly k bits set. In other words, computing u ^ m over all masks m with k bits set gives all words with the desired Hamming distance. Notice that such set of mask does not depend on u.

    That is, for n and t reasonably small, precompute sets of masks with k bits set, for all k in 1,t, and iterate over these sets as required.

    If you don't have enough memory, you may generate the k-bit patterns on the fly. See this discussion for details.

    0 讨论(0)
提交回复
热议问题