在锤距t中生成所有位序列

Generate all sequences of bits within Hamming distance t

本文关键字:      更新时间:2023-10-16

给定位 v的向量,计算带有锤距1的位集合, v,然后 , ,直至输入参数 t

so

011  I should get
~~~ 
111
001
010
~~~ -> 3 choose 1 in number
101
000
110
~~~ -> 3 choose 2
100
~~~ -> 3 choose 3

如何有效地计算这个?向量不会始终是维度3,例如可能是6。这将在我的真实代码中运行很多时间,因此也欢迎一些效率(即使支付更多的内存)。


我的尝试:

#include <iostream>
#include <vector>
void print(const std::vector<char>& v, const int idx, const char new_bit)
{
    for(size_t i = 0; i < v.size(); ++i)
        if(i != idx)
            std::cout << (int)v[i] << " ";
        else
            std::cout << (int)new_bit << " ";
    std::cout << std::endl;
}
void find_near_hamming_dist(const std::vector<char>& v, const int t)
{
    // if t == 1
    for(size_t i = 0; i < v.size(); ++i)
    {
        print(v, i, v[i] ^ 1);
    }
    // I would like to produce t == 2
    // only after ALL the t == 1 results are reported
    /* how to? */
}
int main()
{
    std::vector<char> v = {0, 1, 1};
    find_near_hamming_dist(v, 1);
    return 0; 
}

输出:

MacBook-Pro:hammingDist gsamaras$ g++ -Wall -std=c++0x hammingDist.cpp -o ham
MacBook-Pro:hammingDist gsamaras$ ./ham
1 1 1 
0 0 1 
0 1 0 

首先:kardinality k的hamming dist k位矢量和子集(n aka v.size()的子集)之间存在两次两次射击(已更改位的指数集)。因此,我改为列举更改索引的子集。快速浏览SO历史显示了此参考。当然,您必须跟踪正确的Cardinalitits。

考虑效率可能是毫无意义的,因为无论如何解决问题的方法是指数的。

如果锤距离h(u, v) = k,则u^vk位设置正好。换句话说,用k位集在所有掩码上计算u ^ m的CC_8均具有所需的锤击距离的所有单词。请注意,此类掩码不取决于u

也就是说,对于nt,对于1,t中的所有k,都有相当小的,具有k位的掩模的掩码,并根据需要迭代这些集合。

如果您没有足够的内存,则可以生成k位模式。有关详细信息,请参见此讨论。

#include <stdio.h>
#include <stdint.h>
#include <string.h>
void magic(char* str, int i, int changesLeft) {
        if (changesLeft == 0) {
                printf("%sn", 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("%sn", str);
        size_t len = strlen(str);
        size_t maxDistance = len;
        for (size_t i = 1 ; i <= maxDistance ; ++i) {
                printf("Computing for distance %dn", i);
                magic(str, len-1, i);
                printf("----------------n");
        }
        return 0;
}

输出:

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
----------------

响应kastrinis的回答,我想验证这可以扩展到我的基础示例,例如:

#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 %lun", i);
                magic(str, len-1, i);
                printf("----------------n");
        }
        return 0;
}

输出相同。


ps-我也以不同的方式切换位。

相关文章:
  • 没有找到相关文章